3 Replies - 650 Views - Last Post: 02 April 2013 - 08:26 PM Rate Topic: -----

#1 print('username')  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 61
  • Joined: 18-February 13

Force a program to close when the window is closed?

Posted 02 April 2013 - 04:35 PM

I am writing a simple game engine in C# that uses GDI+, but when the window is closed the program keeps running. I tried all the events, like FormClosed, FormClosing, Application.Exit(), etc. None of them seem to work. Has anyone had this problem and know how to fix it?

Thanks,
Philip
Is This A Good Question/Topic? 0
  • +

Replies To: Force a program to close when the window is closed?

#2 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5509
  • View blog
  • Posts: 11,813
  • Joined: 02-June 10

Re: Force a program to close when the window is closed?

Posted 02 April 2013 - 04:41 PM

You've probably got a thread still running.
You need to clean up your code and logic. I might suggest maybe raising a custom event for "AppClosing" to let all your working threads know they need to close/abort... save settings... save unsaved changes... etc. then close down.


Q:...do multi-threading? Having a problem with cross-threading...
A:

Q: ...Why my multi-thread throws a cross-threading error when it tries to update my GUI?
A: Your thread shouldn't be trying to affect any GUI at all: Ever.
[spoiler]

Quote

But when I kick off the background worker and it goes to change a label in this panel


I'll stop you right there. That underlying principal for your program is the problem and just won't work. The worker is a different thread than the one that created the GUI.

Background threads do not, ever, directly access anything that they didn't make. Period. Accept that and start re-designing.

Background worker raises events. You main class that makes this background worker has to subscribe to those events. Then that thread can update its GUI.

This is how is it meant to work. Each 'thing' in a program really should have only one purpose in life and cause no side affects. The background worker should do its job and nothing else. Its job is not to manage the GUI. The GUI thread's job is to manage the GUI.

Think of it this way: Your car dashboard has one job: To be the GUI for your car. But if the speedometer dies you don't want that to keep the engine from starting. The speedometer and the engine are 'loosely bound' for a reason. Your program is the same. You need the GUI to run whether or not the background worker does, and you want the background worker to run regardless which GUI you have on display.

So the background worker is kept ignorant of which panel you have up. It just says "I'm 50% done". If you have the simple panel or the complex panel on display doesn't matter. It hears the event and does whatever it is designed to do to display those results. Maybe the simple panel uses a progress bar, while the advanced panel display the exact percentage. The background thread doesn't know or care how it is shown.

Quote

So my main application should make a dozen threads to update the dozen similar controls?


To me that sounds like the main application is doing too much work and micromanaging the other controls. If the main application is coded for 12 background threads and panels, what happens in 6 months when you want to add a couple more panels? You have to update all your infrastructure to support them.

Personally I would make UserControls that consist of the Panel, its own backgroundworker and any pure objects that you might want to serialize for later restoration. The idea is to make a complete and fully self-contained 'Lego Block' of functionality. Then use your application to just hook them all together.

Now you can place 2 of your custom controls on screen... or 20... and they each take complete care of themselves. Only when one of your custom controls raises an event like LogThis(string message) or HighLevelWarning(int level) does the application have to do anything. The bulk of the work is done within the UserControl

In each of these UserControls I would create methods for Start() and Stop(). Let the UserControl handle its own needs.

Your main application should do nothing more than:

StartAllPanels()
{
   foreach(CustomPanel cp in myPanelsCollection)
   {
      cp.Start(); // Tell the panel to start
      cp.WarningMessage += WarningHandlerMethod; // Subscribe to warning event
      cp.LogThis += LogMessageHandlerMethod; // Subscribe to logging event
   }
}


See how your main application has no idea what the panel needs to do to start up? It doesn't try to micromanage the panel and tell it to start it's backgroundworker. The main app is blissfully ignorant of the inner needs of the component. Its like a the driver of a car. The driver doesn't tell the car: Close 12v power, start fuel pump, begin ignition computer, calibrate fuel/air mix, confirm foot is on brake, start ignition... The driver just turns the key to Start(). Your application should be the same. It only needs to know what it NEEDS to know. Let the rest of the parts take on as much responsibility as you can push on them.

Spending a little time on these tutorials before writing any more code should help you with a better understanding of all this and enable you to architect a better blueprint for your application. Work smarter not harder.

The tutorials below walk through making an application including inheritance, custom events and custom controls, object serialization and more.
Quick and easy custom events
Bulding an application - Part 1
Building an application - Part 2
Separating data from GUI - PLUS - serializing the data to XML
WPF version (WPF-MVVM data binding)
Passing values between forms/classes
Decouple your multi-threaded work from the GUI so forms don't hang
Was This Post Helpful? 1
  • +
  • -

#3 print('username')  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 61
  • Joined: 18-February 13

Re: Force a program to close when the window is closed?

Posted 02 April 2013 - 04:44 PM

Thanks, for the detailed reply, now I am off to do some code cleaning up.
Was This Post Helpful? 0
  • +
  • -

#4 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3569
  • View blog
  • Posts: 11,089
  • Joined: 05-May 12

Re: Force a program to close when the window is closed?

Posted 02 April 2013 - 08:26 PM

To find out which thread(s) are still running, you can try to exit your program, and then Visual Studio, select Debug.Break. Then after that go to Debug.Windows>Threads, and Debug.Windows>Callstack. As you select each thread in the threads window, you can see the callstack for each thread. This should give you hint as to what is happening on the various threads.
Was This Post Helpful? 2
  • +
  • -

Page 1 of 1