terminating all threads on program exit

  • Thread starter Thread starter Zytan
  • Start date Start date
Z

Zytan

Threads are not auto-terminated when the main form closes (not that
they should be). What's the best way to terminate them when the
program exits? Catch the on close message of the form, and give a
signal to the threads that they must shut down? Seems I need a
destructor for that. Forms don't have an overridable Dispose method.
So, how can I react when the form closes?

Note my example thread just (abnormally) runs forever until it is told
to shut down via boolean data member. So, the form's close method
could just set this. (I know there's the Abort() method, but that
seems ugly, especially since it's not guaranteed to work.)

Zytan
 
Forms don't have an overridable Dispose method.
So, how can I react when the form closes?

FormClosed, FormClosing.

I wonder which is better? I doubt it matters in this case.

Zytan
 
Forms don't have an overridable Dispose method.
FormClosed, FormClosing.

I wonder which is better? I doubt it matters in this case.

http://msdn2.microsoft.com/en-us/library/system.windows.forms.form.formclosing.aspx
"When a form is closed, it is disposed, releasing all resources
associated with the form. If you cancel this event, the form remains
opened."

I thought maybe you can cancel the close if you handle FormClosing.
But, if you are in FormClosed, everything it already disposed, meaning
it's probably too late to signal the threads to close. But, what's
the use of it, then? What could you possibly do in FormClosed if the
form is already disposed? The class data members must still exist,
thus meaning it's not too late to clean up stuff, like closing
threads.

Zytan
 
HI,
I have a same situation.
And my current solution is,
I encapsulate the thread in a class independently,and I have a Stop() public
method to terminal all the thread

//thread proc like this,where m_alive is a private datamember
private void ThreadProc()
{
while(m_alive)
{...}
}

//
public void Stop()
{
m_alive=false;
Thread.Sleep(1000);
}

And in form1.Closing Event of the form which refrence the class,
if (threadClass.Alive) threadClass.Stop();

Also,I wonder this solution althrough is seems working well.

----------------------------------------------------------------------------------------
In my formerly project,I use WinApi with Delphi, The best solution is like
this,

//the procedure of thread
function ThreadProc(const p:Pointer):Cardinal;stdcall;
begin
while WaitMessage do while PeekMessage(m,0,0,0,PM_REMOVE) do begin
case m.message of
WM_QUIT:Exit;
WM_OTHER_MSG:....
end
end;

//when i want to terminal this thread ,just post a message to thread
PostThreadMessage(FThrID,WM_QUIT,0,0);
//where FThrId is the ID of the Thread

How and we do in c#?
How and we post a messge to a thread so that the threadproc can do a certain
thing ?

Waiting for Expert' Response.
 
gshzheng said:
HI,
I have a same situation.
And my current solution is,
I encapsulate the thread in a class independently,and I have a Stop() public
method to terminal all the thread

//thread proc like this,where m_alive is a private datamember
private void ThreadProc()
{
while(m_alive)
{...}
}

//
public void Stop()
{
m_alive=false;
Thread.Sleep(1000);
}

And in form1.Closing Event of the form which refrence the class,
if (threadClass.Alive) threadClass.Stop();

Also,I wonder this solution althrough is seems working well.

Well, you need to be slightly careful - the above isn't guaranteed to
work unless m_alive is volatile.

See http://pobox.com/~skeet/csharp/threads/shutdown.shtml
----------------------------------------------------------------------------------------
In my formerly project,I use WinApi with Delphi, The best solution is like
this,

//the procedure of thread
function ThreadProc(const p:Pointer):Cardinal;stdcall;
begin
while WaitMessage do while PeekMessage(m,0,0,0,PM_REMOVE) do begin
case m.message of
WM_QUIT:Exit;
WM_OTHER_MSG:....
end
end;

//when i want to terminal this thread ,just post a message to thread
PostThreadMessage(FThrID,WM_QUIT,0,0);
//where FThrId is the ID of the Thread

How and we do in c#?
How and we post a messge to a thread so that the threadproc can do a certain
thing ?

You'll need to be running a message pump, and then use something like
Control.BeginInvoke.

However, I wouldn't recommend that solution. I don't see any reason to
bring in windows messages when there are more "pure .NET" ways of doing
it.
 
Thanks,Jon,

Would you pls show me any "pure .NET" way to deal with thread?
I'm a newbie in this area.
 
gshzheng said:
Thanks,Jon,

Would you pls show me any "pure .NET" way to deal with thread?
I'm a newbie in this area.

Did you follow the link in my previous post?
 
Hi all!

I've got two observations:

The .NET forms do have overridable Dispose methods. The reason you
can't override them is because they are already overridden. The
override is in the <Form>.Designer.cs It's safe to modify this method,
the designer won't touch it.

If you use .NET2, the preferable way to create a background worker is
the component BackgroundWorker. It provides you the functionality of
the abovementioned class, however, it is `official'. Also, the
component uses events to communicate with the form, so for example
when you report progress, you don't have to use any Invoke()-s,
because the worker.ProgressChanged event runs in the form's thread.
See http://msdn2.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
for details.
(Sry, I don't know anything about .NET1)

BTW: the FormClosed is your way :)

Rgds

--
av

Sorry :)

I get it.
Thanks again.

Did you follow the link in my previous post?
 
FormClosed, FormClosing.
http://msdn2.microsoft.com/en-us/library/system.windows.forms.form.fo...
"When a form is closed, it is disposed, releasing all resources
associated with the form. If you cancel this event, the form remains
opened."

I thought maybe you can cancel the close if you handle FormClosing.
But, if you are in FormClosed, everything it already disposed, meaning
it's probably too late to signal the threads to close. But, what's
the use of it, then? What could you possibly do in FormClosed if the
form is already disposed? The class data members must still exist,
thus meaning it's not too late to clean up stuff, like closing
threads.

Yup, either can be used. One is just 'better' in that you can stop
shut down if you want. The other, it's too late, you gotta clean up.
Like WM_CLOSE and WM_DESTROY, I believe.

Zytan
 
The .NET forms do have overridable Dispose methods. The reason you
can't override them is because they are already overridden. The
override is in the <Form>.Designer.cs It's safe to modify this method,
the designer won't touch it.

Right, thanks!
If you use .NET2, the preferable way to create a background worker is
the component BackgroundWorker. It provides you the functionality of
the abovementioned class, however, it is `official'. Also, the
component uses events to communicate with the form, so for example
when you report progress, you don't have to use any Invoke()-s,
because the worker.ProgressChanged event runs in the form's thread.
Seehttp://msdn2.microsoft.com/en-us/library/system.componentmodel.backgr...
for details.
(Sry, I don't know anything about .NET1)

Right again! I've used this in VB, actually, and it is a very cool
way to handle worker threads. Good job, .NET. And thanks for
reminding me.
BTW: the FormClosed is your way :)

Yup, thanks, Adam! :)

Zytan
 
Back
Top