Interesting Delay After Thread.Abort()

D

Doug Thews

I ran into an interesting re-pain delay after calling the Abort() method on
a thread, but it only happens the very first time I call it. Every time
afterward, there is no delay.

I've got a delegate inside the UI that I call to update the progress meter.
I use the Suspend() and Abort() methods based on button events.

I can watch the progress meter increase just fine when the thread is
running. When I select Start, I enable the Cancel & Pause buttons (which
call Abort() or Suspend()). The problem happens the very first time I click
Cancel (causing Abort() to be called). I change the status of the Pause &
Cancel buttons back to disabled and I manually clear the progress bar.

What I end up seeing is a 3-4 second delay between the button click and the
actual clearing of the progress bar and disabling of the buttons. I checked
the button_click event handler, and it runs through fine without delay. It
looks as if there's some kind of delay between the event and the re-paint,
but it only happens the very first time. If I Start and Cancel again, the
repaint happens immediately (as I would expect).

I don't have any timers or anything else running that would cause the
re-paint to be intercepted. Is there something about calling Abort() the
very first time that would delay a re-paint (maybe by having to invoke the
GC for the first time for the app or something)?
 
C

C# Learner

I ran into an interesting re-pain delay after calling the Abort() method on
a thread, but it only happens the very first time I call it. Every time
afterward, there is no delay.

I have a feeling that this is caused by the exception that is thrown as a
result of Thread.Abort being called.
 
R

Richard Blewett [DevelopMentor]

Off the top of my head I'm not sure what would cause the delay, but in general should should not call thread.Abort. It is the .NET equivelent of TerminateThread and has similar issues, for example it may terminate a finally block prematurely. There are only two situations where is is OK to call Thread.About

1) when you call it on the current thread (so you know what situation the thread is being ripped down in)
2) when you are pulling down the whole AppDomain

Prefer a cooperative mechanism with flags or calling Thread.Interrupt

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog

nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<#[email protected]>

I ran into an interesting re-pain delay after calling the Abort() method on
a thread, but it only happens the very first time I call it. Every time
afterward, there is no delay.

I've got a delegate inside the UI that I call to update the progress meter.
I use the Suspend() and Abort() methods based on button events.

I can watch the progress meter increase just fine when the thread is
running. When I select Start, I enable the Cancel & Pause buttons (which
call Abort() or Suspend()). The problem happens the very first time I click
Cancel (causing Abort() to be called). I change the status of the Pause &
Cancel buttons back to disabled and I manually clear the progress bar.

What I end up seeing is a 3-4 second delay between the button click and the
actual clearing of the progress bar and disabling of the buttons. I checked
the button_click event handler, and it runs through fine without delay. It
looks as if there's some kind of delay between the event and the re-paint,
but it only happens the very first time. If I Start and Cancel again, the
repaint happens immediately (as I would expect).

I don't have any timers or anything else running that would cause the
re-paint to be intercepted. Is there something about calling Abort() the
very first time that would delay a re-paint (maybe by having to invoke the
GC for the first time for the app or something)?

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/





---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004



[microsoft.public.dotnet.languages.csharp]
 
D

Doug Thews

But if you know you're going to get rid of the thread permanently, why not
call Thread.Abort()? Thread.Interrupt() leaves all the resources in tact,
and I want to force the GC to collect those resources.

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/



Richard Blewett said:
Off the top of my head I'm not sure what would cause the delay, but in
general should should not call thread.Abort. It is the .NET equivelent of
TerminateThread and has similar issues, for example it may terminate a
finally block prematurely. There are only two situations where is is OK to
call Thread.About

1) when you call it on the current thread (so you know what situation the
thread is being ripped down in)
2) when you are pulling down the whole AppDomain

Prefer a cooperative mechanism with flags or calling Thread.Interrupt

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog


nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<#[email protected]>

I ran into an interesting re-pain delay after calling the Abort() method
on
a thread, but it only happens the very first time I call it. Every time
afterward, there is no delay.

I've got a delegate inside the UI that I call to update the progress
meter.
I use the Suspend() and Abort() methods based on button events.

I can watch the progress meter increase just fine when the thread is
running. When I select Start, I enable the Cancel & Pause buttons (which
call Abort() or Suspend()). The problem happens the very first time I
click
Cancel (causing Abort() to be called). I change the status of the Pause &
Cancel buttons back to disabled and I manually clear the progress bar.

What I end up seeing is a 3-4 second delay between the button click and
the
actual clearing of the progress bar and disabling of the buttons. I
checked
the button_click event handler, and it runs through fine without delay. It
looks as if there's some kind of delay between the event and the re-paint,
but it only happens the very first time. If I Start and Cancel again, the
repaint happens immediately (as I would expect).

I don't have any timers or anything else running that would cause the
re-paint to be intercepted. Is there something about calling Abort() the
very first time that would delay a re-paint (maybe by having to invoke the
GC for the first time for the app or something)?

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/





---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004



[microsoft.public.dotnet.languages.csharp]
 
R

Richard Blewett [DevelopMentor]

Hmmm, what makes you believe that?

Thread.Interrupt throws a ThreadInterruptedException on the thread that can be caught, handled and if the thread really wanted to swallowed.

Thread.Abort throws a ThreadAbortException on the thread that can be caught, handled but cannot be swallowed as the runtime will re-throw the exception.

The problem with Thread.Abort isn't that it may trash the executing thread, the problem is it may trash your entire AppDomain as it rips the ground from underneath the executing thread - as I said possibly throwing in the middle of a finally block. This is not a recipe for stability.

The thing that will free up the thread's resources is the termination of the thread and the lack of any live references to that thread object. Thread.Interrupt should be able to bring the thread down as long as someone hasn't purposefully tried to stop it. The problem is that that the operating system doesn't have an API to force a thread to terminate without destabilizing the process so how would .NET achieve this? At least having the thread as a managed resource the damage can be limited to the AppDomain.

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog

nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<[email protected]>

But if you know you're going to get rid of the thread permanently, why not
call Thread.Abort()? Thread.Interrupt() leaves all the resources in tact,
and I want to force the GC to collect those resources.

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/



Richard Blewett said:
Off the top of my head I'm not sure what would cause the delay, but in
general should should not call thread.Abort. It is the .NET equivelent of
TerminateThread and has similar issues, for example it may terminate a
finally block prematurely. There are only two situations where is is OK to
call Thread.About

1) when you call it on the current thread (so you know what situation the
thread is being ripped down in)
2) when you are pulling down the whole AppDomain

Prefer a cooperative mechanism with flags or calling Thread.Interrupt

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog


nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<#[email protected]>

I ran into an interesting re-pain delay after calling the Abort() method
on
a thread, but it only happens the very first time I call it. Every time
afterward, there is no delay.

I've got a delegate inside the UI that I call to update the progress
meter.
I use the Suspend() and Abort() methods based on button events.

I can watch the progress meter increase just fine when the thread is
running. When I select Start, I enable the Cancel & Pause buttons (which
call Abort() or Suspend()). The problem happens the very first time I
click
Cancel (causing Abort() to be called). I change the status of the Pause &
Cancel buttons back to disabled and I manually clear the progress bar.

What I end up seeing is a 3-4 second delay between the button click and
the
actual clearing of the progress bar and disabling of the buttons. I
checked
the button_click event handler, and it runs through fine without delay. It
looks as if there's some kind of delay between the event and the re-paint,
but it only happens the very first time. If I Start and Cancel again, the
repaint happens immediately (as I would expect).

I don't have any timers or anything else running that would cause the
re-paint to be intercepted. Is there something about calling Abort() the
very first time that would delay a re-paint (maybe by having to invoke the
GC for the first time for the app or something)?

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/





---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004



[microsoft.public.dotnet.languages.csharp]



---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004



[microsoft.public.dotnet.languages.csharp]
 
W

William Stacey [MVP]

Normally, in your worker threads you block once waiting on some blocking
read or other, process the read/write and loop. In these cases, you may be
able to useWaitHandle.WaitAny and wait on a cancel ManualResetEvent event
and your other wait object. That way, if you signal your cancel handle, you
can break out clean without needing Abort or Interrupt. So in your
shutdown, you can do that first, test for exit, then do an Interrupt if no
shutdown. If still no joy, do the abort as last resort.

--
William Stacey, MVP

Doug Thews said:
But if you know you're going to get rid of the thread permanently, why not
call Thread.Abort()? Thread.Interrupt() leaves all the resources in tact,
and I want to force the GC to collect those resources.

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/



Richard Blewett said:
Off the top of my head I'm not sure what would cause the delay, but in
general should should not call thread.Abort. It is the .NET equivelent of
TerminateThread and has similar issues, for example it may terminate a
finally block prematurely. There are only two situations where is is OK to
call Thread.About

1) when you call it on the current thread (so you know what situation the
thread is being ripped down in)
2) when you are pulling down the whole AppDomain

Prefer a cooperative mechanism with flags or calling Thread.Interrupt

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog
nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/ said:
I ran into an interesting re-pain delay after calling the Abort() method
on
a thread, but it only happens the very first time I call it. Every time
afterward, there is no delay.

I've got a delegate inside the UI that I call to update the progress
meter.
I use the Suspend() and Abort() methods based on button events.

I can watch the progress meter increase just fine when the thread is
running. When I select Start, I enable the Cancel & Pause buttons (which
call Abort() or Suspend()). The problem happens the very first time I
click
Cancel (causing Abort() to be called). I change the status of the Pause &
Cancel buttons back to disabled and I manually clear the progress bar.

What I end up seeing is a 3-4 second delay between the button click and
the
actual clearing of the progress bar and disabling of the buttons. I
checked
the button_click event handler, and it runs through fine without delay. It
looks as if there's some kind of delay between the event and the re-paint,
but it only happens the very first time. If I Start and Cancel again, the
repaint happens immediately (as I would expect).

I don't have any timers or anything else running that would cause the
re-paint to be intercepted. Is there something about calling Abort() the
very first time that would delay a re-paint (maybe by having to invoke the
GC for the first time for the app or something)?

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/





---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004



[microsoft.public.dotnet.languages.csharp]
 
D

Doug Thews

So, if I have a self-sustained business operation that doesn't need anything
from the thread that started it, I should use Thread.Interrupt()? Once I do
that, what else do I need to do to make sure that the objects that were
instantiated within the thread are GC'ed (maybe a web service connection,
database connection, or some other high-overhead resource)?

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/



William Stacey said:
Normally, in your worker threads you block once waiting on some blocking
read or other, process the read/write and loop. In these cases, you may
be
able to useWaitHandle.WaitAny and wait on a cancel ManualResetEvent event
and your other wait object. That way, if you signal your cancel handle,
you
can break out clean without needing Abort or Interrupt. So in your
shutdown, you can do that first, test for exit, then do an Interrupt if
no
shutdown. If still no joy, do the abort as last resort.

--
William Stacey, MVP

Doug Thews said:
But if you know you're going to get rid of the thread permanently, why
not
call Thread.Abort()? Thread.Interrupt() leaves all the resources in
tact,
and I want to force the GC to collect those resources.

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/



Richard Blewett said:
Off the top of my head I'm not sure what would cause the delay, but in
general should should not call thread.Abort. It is the .NET equivelent of
TerminateThread and has similar issues, for example it may terminate a
finally block prematurely. There are only two situations where is is OK to
call Thread.About

1) when you call it on the current thread (so you know what situation the
thread is being ripped down in)
2) when you are pulling down the whole AppDomain

Prefer a cooperative mechanism with flags or calling Thread.Interrupt

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog
nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/ said:
I ran into an interesting re-pain delay after calling the Abort()
method
on
a thread, but it only happens the very first time I call it. Every time
afterward, there is no delay.

I've got a delegate inside the UI that I call to update the progress
meter.
I use the Suspend() and Abort() methods based on button events.

I can watch the progress meter increase just fine when the thread is
running. When I select Start, I enable the Cancel & Pause buttons
(which
call Abort() or Suspend()). The problem happens the very first time I
click
Cancel (causing Abort() to be called). I change the status of the Pause &
Cancel buttons back to disabled and I manually clear the progress bar.

What I end up seeing is a 3-4 second delay between the button click and
the
actual clearing of the progress bar and disabling of the buttons. I
checked
the button_click event handler, and it runs through fine without delay. It
looks as if there's some kind of delay between the event and the re-paint,
but it only happens the very first time. If I Start and Cancel again, the
repaint happens immediately (as I would expect).

I don't have any timers or anything else running that would cause the
re-paint to be intercepted. Is there something about calling Abort()
the
very first time that would delay a re-paint (maybe by having to invoke the
GC for the first time for the app or something)?

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/





---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004



[microsoft.public.dotnet.languages.csharp]
 
D

Doug Thews

I think you're on to something here. I already have a catch mechanism
inside the thread code, but it's almost like the delay is caused by
something external needing to be loaded once the first exception (via the
abort) is hit. After that, the delays go away because whatever 'external'
stuff that needed to be loaded, is now already resident.

For those who asked about Thread.Interrupt(), it's not what I'm looking for.
According to the docs, I should be able to use Thread.Abort() and
immediately follow it with a Thread.Join() to make sure that the thread
stays blocked until it's eliminated. I don't want to keep the thread in a
wait/sleep state, so Interrupt() is not what I'm looking for. There is no
mention of Abort() followed by Join() bringing down an entire AppDomain, so
if you have some other docs to look at, I'd appreciate a link.

Thanks in advance.
 
W

William Stacey [MVP]

Once you break out of your while loop, then your on your way out of the
thread. So process your Close() method after the while loop breaks or in a
Finally block if your wrapping your while in a Try/Catch. Close down your
resources (i.e. sockets, web services, etc like normal in your close.
Normal GC will handle any managed resources when they loose their last
reference. As to your first question, I would break on event first if
possible, then Interrupt if can't break out for some reason. Only then use
Abort if nothing else works. hth

--
William Stacey, MVP

Doug Thews said:
So, if I have a self-sustained business operation that doesn't need anything
from the thread that started it, I should use Thread.Interrupt()? Once I do
that, what else do I need to do to make sure that the objects that were
instantiated within the thread are GC'ed (maybe a web service connection,
database connection, or some other high-overhead resource)?

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/



William Stacey said:
Normally, in your worker threads you block once waiting on some blocking
read or other, process the read/write and loop. In these cases, you may
be
able to useWaitHandle.WaitAny and wait on a cancel ManualResetEvent event
and your other wait object. That way, if you signal your cancel handle,
you
can break out clean without needing Abort or Interrupt. So in your
shutdown, you can do that first, test for exit, then do an Interrupt if
no
shutdown. If still no joy, do the abort as last resort.

--
William Stacey, MVP

Doug Thews said:
But if you know you're going to get rid of the thread permanently, why
not
call Thread.Abort()? Thread.Interrupt() leaves all the resources in
tact,
and I want to force the GC to collect those resources.

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/



Off the top of my head I'm not sure what would cause the delay, but in
general should should not call thread.Abort. It is the .NET
equivelent
of
TerminateThread and has similar issues, for example it may terminate a
finally block prematurely. There are only two situations where is is
OK
to
call Thread.About

1) when you call it on the current thread (so you know what situation the
thread is being ripped down in)
2) when you are pulling down the whole AppDomain

Prefer a cooperative mechanism with flags or calling Thread.Interrupt

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog
nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/ said:
I ran into an interesting re-pain delay after calling the Abort()
method
on
a thread, but it only happens the very first time I call it. Every time
afterward, there is no delay.

I've got a delegate inside the UI that I call to update the progress
meter.
I use the Suspend() and Abort() methods based on button events.

I can watch the progress meter increase just fine when the thread is
running. When I select Start, I enable the Cancel & Pause buttons
(which
call Abort() or Suspend()). The problem happens the very first time I
click
Cancel (causing Abort() to be called). I change the status of the
Pause
&
Cancel buttons back to disabled and I manually clear the progress bar.

What I end up seeing is a 3-4 second delay between the button click and
the
actual clearing of the progress bar and disabling of the buttons. I
checked
the button_click event handler, and it runs through fine without
delay.
It
looks as if there's some kind of delay between the event and the re-paint,
but it only happens the very first time. If I Start and Cancel again, the
repaint happens immediately (as I would expect).

I don't have any timers or anything else running that would cause the
re-paint to be intercepted. Is there something about calling Abort()
the
very first time that would delay a re-paint (maybe by having to
invoke
the
GC for the first time for the app or something)?

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/





---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004



[microsoft.public.dotnet.languages.csharp]
 
R

Richard Blewett [DevelopMentor]

The objects used in the thread will be GC'd when then are no longer referenced by any active code and the GC gets around to running. Its a good idead to use try ... finally to clean up your non-memory resources in a timely fashion (without having to wait for the GC and finalization) such as closing FileStreams, SqlConnections, etc.

However, I have to disagree on one point. I would advise not to call Thread.Abort in any circumstances unless you are bringing down the AppDomain or terminating the application. If you do you may hose your running AppDomain and that is really not a good idea if you intend to carry on running. If the thread won't stop, log the fact so you can investigate later (as it probably means you have a bug somewhere) and leave it as a zombie until your application exits.

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog

nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<[email protected]>

Once you break out of your while loop, then your on your way out of the
thread. So process your Close() method after the while loop breaks or in a
Finally block if your wrapping your while in a Try/Catch. Close down your
resources (i.e. sockets, web services, etc like normal in your close.
Normal GC will handle any managed resources when they loose their last
reference. As to your first question, I would break on event first if
possible, then Interrupt if can't break out for some reason. Only then use
Abort if nothing else works. hth

--
William Stacey, MVP

Doug Thews said:
So, if I have a self-sustained business operation that doesn't need anything
from the thread that started it, I should use Thread.Interrupt()? Once I do
that, what else do I need to do to make sure that the objects that were
instantiated within the thread are GC'ed (maybe a web service connection,
database connection, or some other high-overhead resource)?

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/



William Stacey said:
Normally, in your worker threads you block once waiting on some blocking
read or other, process the read/write and loop. In these cases, you may
be
able to useWaitHandle.WaitAny and wait on a cancel ManualResetEvent event
and your other wait object. That way, if you signal your cancel handle,
you
can break out clean without needing Abort or Interrupt. So in your
shutdown, you can do that first, test for exit, then do an Interrupt if
no
shutdown. If still no joy, do the abort as last resort.

--
William Stacey, MVP

Doug Thews said:
But if you know you're going to get rid of the thread permanently, why
not
call Thread.Abort()? Thread.Interrupt() leaves all the resources in
tact,
and I want to force the GC to collect those resources.

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/



Off the top of my head I'm not sure what would cause the delay, but in
general should should not call thread.Abort. It is the .NET
equivelent
of
TerminateThread and has similar issues, for example it may terminate a
finally block prematurely. There are only two situations where is is
OK
to
call Thread.About

1) when you call it on the current thread (so you know what situation the
thread is being ripped down in)
2) when you are pulling down the whole AppDomain

Prefer a cooperative mechanism with flags or calling Thread.Interrupt

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog
nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/ said:
I ran into an interesting re-pain delay after calling the Abort()
method
on
a thread, but it only happens the very first time I call it. Every time
afterward, there is no delay.

I've got a delegate inside the UI that I call to update the progress
meter.
I use the Suspend() and Abort() methods based on button events.

I can watch the progress meter increase just fine when the thread is
running. When I select Start, I enable the Cancel & Pause buttons
(which
call Abort() or Suspend()). The problem happens the very first time I
click
Cancel (causing Abort() to be called). I change the status of the
Pause
&
Cancel buttons back to disabled and I manually clear the progress bar.

What I end up seeing is a 3-4 second delay between the button click and
the
actual clearing of the progress bar and disabling of the buttons. I
checked
the button_click event handler, and it runs through fine without
delay.
It
looks as if there's some kind of delay between the event and the re-paint,
but it only happens the very first time. If I Start and Cancel again, the
repaint happens immediately (as I would expect).

I don't have any timers or anything else running that would cause the
re-paint to be intercepted. Is there something about calling Abort()
the
very first time that would delay a re-paint (maybe by having to
invoke
the
GC for the first time for the app or something)?

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/





---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004



[microsoft.public.dotnet.languages.csharp]


---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004



[microsoft.public.dotnet.languages.csharp]
 
D

Doug Thews

Great, thanks for the info. Do you have a ptr to the docs that show calling
Abort() will bring down the AppDomain or cause "unstable" results? I can't
find any MS docs on this particular topic.

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/



Richard Blewett said:
The objects used in the thread will be GC'd when then are no longer
referenced by any active code and the GC gets around to running. Its a
good idead to use try ... finally to clean up your non-memory resources in
a timely fashion (without having to wait for the GC and finalization) such
as closing FileStreams, SqlConnections, etc.

However, I have to disagree on one point. I would advise not to call
Thread.Abort in any circumstances unless you are bringing down the
AppDomain or terminating the application. If you do you may hose your
running AppDomain and that is really not a good idea if you intend to
carry on running. If the thread won't stop, log the fact so you can
investigate later (as it probably means you have a bug somewhere) and
leave it as a zombie until your application exits.

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog


nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<[email protected]>

Once you break out of your while loop, then your on your way out of the
thread. So process your Close() method after the while loop breaks or in a
Finally block if your wrapping your while in a Try/Catch. Close down your
resources (i.e. sockets, web services, etc like normal in your close.
Normal GC will handle any managed resources when they loose their last
reference. As to your first question, I would break on event first if
possible, then Interrupt if can't break out for some reason. Only then use
Abort if nothing else works. hth

--
William Stacey, MVP

Doug Thews said:
So, if I have a self-sustained business operation that doesn't need anything
from the thread that started it, I should use Thread.Interrupt()? Once I do
that, what else do I need to do to make sure that the objects that were
instantiated within the thread are GC'ed (maybe a web service
connection,
database connection, or some other high-overhead resource)?

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/



William Stacey said:
Normally, in your worker threads you block once waiting on some
blocking
read or other, process the read/write and loop. In these cases, you
may
be
able to useWaitHandle.WaitAny and wait on a cancel ManualResetEvent event
and your other wait object. That way, if you signal your cancel
handle,
you
can break out clean without needing Abort or Interrupt. So in your
shutdown, you can do that first, test for exit, then do an Interrupt
if
no
shutdown. If still no joy, do the abort as last resort.

--
William Stacey, MVP

But if you know you're going to get rid of the thread permanently,
why
not
call Thread.Abort()? Thread.Interrupt() leaves all the resources in
tact,
and I want to force the GC to collect those resources.

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/



Off the top of my head I'm not sure what would cause the delay, but in
general should should not call thread.Abort. It is the .NET equivelent
of
TerminateThread and has similar issues, for example it may
terminate a
finally block prematurely. There are only two situations where is
is OK
to
call Thread.About

1) when you call it on the current thread (so you know what
situation
the
thread is being ripped down in)
2) when you are pulling down the whole AppDomain

Prefer a cooperative mechanism with flags or calling
Thread.Interrupt

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog
nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/ said:
I ran into an interesting re-pain delay after calling the Abort()
method
on
a thread, but it only happens the very first time I call it. Every time
afterward, there is no delay.

I've got a delegate inside the UI that I call to update the
progress
meter.
I use the Suspend() and Abort() methods based on button events.

I can watch the progress meter increase just fine when the thread
is
running. When I select Start, I enable the Cancel & Pause buttons
(which
call Abort() or Suspend()). The problem happens the very first time
I
click
Cancel (causing Abort() to be called). I change the status of the Pause
&
Cancel buttons back to disabled and I manually clear the progress bar.

What I end up seeing is a 3-4 second delay between the button click and
the
actual clearing of the progress bar and disabling of the buttons. I
checked
the button_click event handler, and it runs through fine without delay.
It
looks as if there's some kind of delay between the event and the
re-paint,
but it only happens the very first time. If I Start and Cancel
again,
the
repaint happens immediately (as I would expect).

I don't have any timers or anything else running that would cause
the
re-paint to be intercepted. Is there something about calling
Abort()
the
very first time that would delay a re-paint (maybe by having to invoke
the
GC for the first time for the app or something)?

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/





---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004



[microsoft.public.dotnet.languages.csharp]


---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004



[microsoft.public.dotnet.languages.csharp]
 
R

Richard Blewett [DevelopMentor]

nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<##[email protected]>

Great, thanks for the info. Do you have a ptr to the docs that show calling
Abort() will bring down the AppDomain or cause "unstable" results? I can't
find any MS docs on this particular topic.
 
W

Willy Denoyette [MVP]

Read Chris Brumme's (one of the CLR architects) Blog for some of his
thoughts:
http://blogs.gotdotnet.com/cbrumme/PermaLink.aspx/dac5ba4a-f0c8-42bb-a5cf-097efb25d1a9

also something related from the same author:
http://blogs.msdn.com/cbrumme/archive/2003/06/23/51482.aspx

Willy.

Doug Thews said:
Great, thanks for the info. Do you have a ptr to the docs that show
calling Abort() will bring down the AppDomain or cause "unstable" results?
I can't find any MS docs on this particular topic.

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/



Richard Blewett said:
The objects used in the thread will be GC'd when then are no longer
referenced by any active code and the GC gets around to running. Its a
good idead to use try ... finally to clean up your non-memory resources
in a timely fashion (without having to wait for the GC and finalization)
such as closing FileStreams, SqlConnections, etc.

However, I have to disagree on one point. I would advise not to call
Thread.Abort in any circumstances unless you are bringing down the
AppDomain or terminating the application. If you do you may hose your
running AppDomain and that is really not a good idea if you intend to
carry on running. If the thread won't stop, log the fact so you can
investigate later (as it probably means you have a bug somewhere) and
leave it as a zombie until your application exits.

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog


nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<[email protected]>

Once you break out of your while loop, then your on your way out of the
thread. So process your Close() method after the while loop breaks or in
a
Finally block if your wrapping your while in a Try/Catch. Close down your
resources (i.e. sockets, web services, etc like normal in your close.
Normal GC will handle any managed resources when they loose their last
reference. As to your first question, I would break on event first if
possible, then Interrupt if can't break out for some reason. Only then
use
Abort if nothing else works. hth

--
William Stacey, MVP

Doug Thews said:
So, if I have a self-sustained business operation that doesn't need anything
from the thread that started it, I should use Thread.Interrupt()? Once
I do
that, what else do I need to do to make sure that the objects that were
instantiated within the thread are GC'ed (maybe a web service
connection,
database connection, or some other high-overhead resource)?

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/



Normally, in your worker threads you block once waiting on some
blocking
read or other, process the read/write and loop. In these cases, you
may
be
able to useWaitHandle.WaitAny and wait on a cancel ManualResetEvent event
and your other wait object. That way, if you signal your cancel
handle,
you
can break out clean without needing Abort or Interrupt. So in your
shutdown, you can do that first, test for exit, then do an Interrupt
if
no
shutdown. If still no joy, do the abort as last resort.

--
William Stacey, MVP

But if you know you're going to get rid of the thread permanently,
why
not
call Thread.Abort()? Thread.Interrupt() leaves all the resources in
tact,
and I want to force the GC to collect those resources.

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/



Off the top of my head I'm not sure what would cause the delay,
but in
general should should not call thread.Abort. It is the .NET equivelent
of
TerminateThread and has similar issues, for example it may
terminate a
finally block prematurely. There are only two situations where is
is OK
to
call Thread.About

1) when you call it on the current thread (so you know what
situation
the
thread is being ripped down in)
2) when you are pulling down the whole AppDomain

Prefer a cooperative mechanism with flags or calling
Thread.Interrupt

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog
nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/ said:
I ran into an interesting re-pain delay after calling the Abort()
method
on
a thread, but it only happens the very first time I call it. Every time
afterward, there is no delay.

I've got a delegate inside the UI that I call to update the
progress
meter.
I use the Suspend() and Abort() methods based on button events.

I can watch the progress meter increase just fine when the thread
is
running. When I select Start, I enable the Cancel & Pause buttons
(which
call Abort() or Suspend()). The problem happens the very first
time I
click
Cancel (causing Abort() to be called). I change the status of the Pause
&
Cancel buttons back to disabled and I manually clear the progress bar.

What I end up seeing is a 3-4 second delay between the button
click and
the
actual clearing of the progress bar and disabling of the buttons.
I
checked
the button_click event handler, and it runs through fine without delay.
It
looks as if there's some kind of delay between the event and the
re-paint,
but it only happens the very first time. If I Start and Cancel
again,
the
repaint happens immediately (as I would expect).

I don't have any timers or anything else running that would cause
the
re-paint to be intercepted. Is there something about calling
Abort()
the
very first time that would delay a re-paint (maybe by having to invoke
the
GC for the first time for the app or something)?

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/





---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004



[microsoft.public.dotnet.languages.csharp]


---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004



[microsoft.public.dotnet.languages.csharp]
 
D

Doug Thews

Thanks a lot guys for the doc ptrs. The newsgroup one expired, but I'll
check over on the blogs mentioned. I would've thought that this effect
would've been documented in somewhere in the Thread class documentation.
 
D

Doug Thews

Maybe I'm being naive about this, but if Abort() actually destroys the
AppDomain, then why does my Main() code (the main thread that spun the
worker thread) still seem to work after the Abort()? The way I understand
it, the worker thread runs under the same AppDomain as the thread that spun
it, correct?

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/



Willy Denoyette said:
Read Chris Brumme's (one of the CLR architects) Blog for some of his
thoughts:
http://blogs.gotdotnet.com/cbrumme/PermaLink.aspx/dac5ba4a-f0c8-42bb-a5cf-097efb25d1a9

also something related from the same author:
http://blogs.msdn.com/cbrumme/archive/2003/06/23/51482.aspx

Willy.

Doug Thews said:
Great, thanks for the info. Do you have a ptr to the docs that show
calling Abort() will bring down the AppDomain or cause "unstable"
results? I can't find any MS docs on this particular topic.

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/



Richard Blewett said:
The objects used in the thread will be GC'd when then are no longer
referenced by any active code and the GC gets around to running. Its a
good idead to use try ... finally to clean up your non-memory resources
in a timely fashion (without having to wait for the GC and finalization)
such as closing FileStreams, SqlConnections, etc.

However, I have to disagree on one point. I would advise not to call
Thread.Abort in any circumstances unless you are bringing down the
AppDomain or terminating the application. If you do you may hose your
running AppDomain and that is really not a good idea if you intend to
carry on running. If the thread won't stop, log the fact so you can
investigate later (as it probably means you have a bug somewhere) and
leave it as a zombie until your application exits.

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog


nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<[email protected]>

Once you break out of your while loop, then your on your way out of the
thread. So process your Close() method after the while loop breaks or in
a
Finally block if your wrapping your while in a Try/Catch. Close down
your
resources (i.e. sockets, web services, etc like normal in your close.
Normal GC will handle any managed resources when they loose their last
reference. As to your first question, I would break on event first if
possible, then Interrupt if can't break out for some reason. Only then
use
Abort if nothing else works. hth

--
William Stacey, MVP

So, if I have a self-sustained business operation that doesn't need
anything
from the thread that started it, I should use Thread.Interrupt()? Once
I
do
that, what else do I need to do to make sure that the objects that
were
instantiated within the thread are GC'ed (maybe a web service
connection,
database connection, or some other high-overhead resource)?

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/



Normally, in your worker threads you block once waiting on some
blocking
read or other, process the read/write and loop. In these cases, you
may
be
able to useWaitHandle.WaitAny and wait on a cancel ManualResetEvent
event
and your other wait object. That way, if you signal your cancel
handle,
you
can break out clean without needing Abort or Interrupt. So in your
shutdown, you can do that first, test for exit, then do an Interrupt
if
no
shutdown. If still no joy, do the abort as last resort.

--
William Stacey, MVP

But if you know you're going to get rid of the thread permanently,
why
not
call Thread.Abort()? Thread.Interrupt() leaves all the resources in
tact,
and I want to force the GC to collect those resources.

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/



message
Off the top of my head I'm not sure what would cause the delay,
but
in
general should should not call thread.Abort. It is the .NET
equivelent
of
TerminateThread and has similar issues, for example it may
terminate
a
finally block prematurely. There are only two situations where is
is
OK
to
call Thread.About

1) when you call it on the current thread (so you know what
situation
the
thread is being ripped down in)
2) when you are pulling down the whole AppDomain

Prefer a cooperative mechanism with flags or calling
Thread.Interrupt

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog




nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<#[email protected]>

I ran into an interesting re-pain delay after calling the Abort()
method
on
a thread, but it only happens the very first time I call it.
Every
time
afterward, there is no delay.

I've got a delegate inside the UI that I call to update the
progress
meter.
I use the Suspend() and Abort() methods based on button events.

I can watch the progress meter increase just fine when the thread
is
running. When I select Start, I enable the Cancel & Pause buttons
(which
call Abort() or Suspend()). The problem happens the very first
time I
click
Cancel (causing Abort() to be called). I change the status of the
Pause
&
Cancel buttons back to disabled and I manually clear the progress
bar.

What I end up seeing is a 3-4 second delay between the button
click
and
the
actual clearing of the progress bar and disabling of the buttons.
I
checked
the button_click event handler, and it runs through fine without
delay.
It
looks as if there's some kind of delay between the event and the
re-paint,
but it only happens the very first time. If I Start and Cancel
again,
the
repaint happens immediately (as I would expect).

I don't have any timers or anything else running that would cause
the
re-paint to be intercepted. Is there something about calling
Abort()
the
very first time that would delay a re-paint (maybe by having to
invoke
the
GC for the first time for the app or something)?

--
Doug Thews
Director, Customer Solutions
D&D Consulting Services
----------------
Visit my Tech Blog at:
http://www.ddconsult.com/blogs/illuminati/





---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004



[microsoft.public.dotnet.languages.csharp]







---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004



[microsoft.public.dotnet.languages.csharp]
 
R

Richard Blewett [DevelopMentor]

It doesn't destroy the AppDomain, it *may* trash the AppDomain depending on what the code was doing when the ThreadAbortException was thrown. Its a bit like updating the UI from a worker thread - its seems to work except when your boss is watching you demo the system ;-)

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog

nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<Ob6Nds#[email protected]>

Maybe I'm being naive about this, but if Abort() actually destroys the
AppDomain, then why does my Main() code (the main thread that spun the
worker thread) still seem to work after the Abort()? The way I understand
it, the worker thread runs under the same AppDomain as the thread that spun
it, correct?
 
D

Doug Thews

I got it. Since everything is compartmentalized (just doing some offline
work that I don't need done in the foreground), it doesn't seem like Abort()
will harm me any. I can see where Abort() could harm you if you're updating
a UI control directly from within the thread, but that's not what this guy
does (not should a worker thread ever update a UI control directly - that's
what Delegates are for).
 
W

Willy Denoyette [MVP]

Fortunately v2.0 solves a number of (scary) issues like leaking handles
(handles are/can be wrapped by a SafeHandle class) and aborting finally
blocks.
But for now you are right, asynchronous (Thread) Aborts are evil. You better
shutdown the process or Appdomain or change your design so you can use
synchronous Aborts.

Willy.
 
R

Richard Blewett [DevelopMentor]

Hold on - I was using UI updating from the wrong thread as illustrative of things that appear to work alot of the time but can have really bad consequences. Please don't call Thread.Abort, you have absolutely no idea of what state things will be left in afterwards. What if your code is performing a finally block, wgar if your thread has ownership of a lock, what if your thread we in the middle of updating static state that it now leaves inconsistent. There are numerous things that can go very wrong so just accept that if you get to the point of having to issue an Abort to bring the thread down:

1) The thread may be performing unmanaged work and so the Abort still won't bring the thread down
2) You probably have a bug in your code which needs fixing.

Just log the fact that the thread won't terminate (so you can investigate later), store a reference to the frozen thread somewhere and just create a new thread to perform more work if you need to. When you come to process shutdown check to see if the thread has now finished and if it hasn't then Abort the thread.

Btw: delegates on their own are not a solution for updating the UI from a background thread, you still have to make the delegate invocation run on the UI thread via Control.BeginInvoke

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog

nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<[email protected]>

I got it. Since everything is compartmentalized (just doing some offline
work that I don't need done in the foreground), it doesn't seem like Abort()
will harm me any. I can see where Abort() could harm you if you're updating
a UI control directly from within the thread, but that's not what this guy
does (not should a worker thread ever update a UI control directly - that's
what Delegates are for).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top