Re: Thread.Abort [LONG]
- From: Christoph Nahr <christoph.nahr@xxxxxxxxxxxxx>
- Date: Fri, 19 Aug 2005 09:46:38 +0200
On Fri, 19 Aug 2005 00:34:17 +0200, "Willy Denoyette [MVP]"
<willy.denoyette@xxxxxxxxxx> wrote:
>Why? because you don't like it or you because you think I'm wrong. If it's
>the latter we will have to agree to disagree.
>Maybe it's too strongly worded, but following is what's been suggested by
>devs. on the CLR team (C Brumme, J. Duffy) and outside Microsoft; "Most code
>should never try to abort an opaque thread..." "It's recommended that
>Framework code is written with the assumption that an abort will shortly be
>followed by a AD unload".
I think the key word here is "an *opaque* thread". If this means "a
thread whose code you don't know" then I'll agree. That's no reason
not to use Thread.Abort on threads whose code you know, though.
>Really and what about this:
>
>using(Resource r = new(...)
>{
>..
>}
> where the resource acquisition occurs outside the try block (if you look at
>what's been emitted by the C# compiler), that means that finally won't run
>(Dispose won't be called) in the presence of an Asynchronous exception like
>ThreadAbort that occurs after acquiring but before assignment of the
>reference to r, there goes your deterministic clean-up, so you are at the
>mercy of the finalizer to release the resource acquired.
I admit that's a tricky issue but the solution is simple -- use
explicit try/finally instead. And since the finalizer *will* release
the resource eventually I don't see why this is such a big issue.
But the real problem here is the possibility of interrupting the
assignment expression which you mention below.
>Suppose you are interrupted by a thread abort while modifying a complex data
>structure (a container), leaving the container in a partly modified state.
>Your container is corrupted, right?
>No problem you say, the GC will clean-up the garbage when there is only one
>single reference, but what if this container was shared between threads?
If there's any chance of asynchronous interruptions then obviously the
background threads must not modify shared containers; they should
modify private copies which are then copied back to the main thread
when calculation is complete and known to have succeeded.
Alternatively, they could invoke back to the main thread for making
changes. Usually you can't just secretly modify shared data in
another thread anyway since some part of the main thread needs to know
about the change, update related data or the UI or whatever.
(As an aside, this is also one reason why I believe the old
Synchronized wrappers for the non-generic collections were a horrible,
horrible idea. They might trick people into doing exactly what you
propose here, assuming that everything is "thread-safe" because the
documentation says so...)
>No it isn't, if the abort occurs after memory allocation but before ptr
>assignment, you'll end with ptr still being "null" when your finally runs,
>bummer memory leak. This isn't an issue when you unload the AD, but what if
>you continue to execute code inside this domain?
Okay, that's a really good point. Hmm... I suppose the only way to
avoid this is to not allocate any critical resources within code
blocks where Thread.Abort is possible. You could always use Monitor
locks to protect such blocks, though; or allocate resources in the
main thread before handing the references over to the worker thread.
The possibility of a ThreadAbortException interrupting a reference
assignment is really aggravating, though. I'd say that calls for some
kind of IL primitive that prevents a statement sequence from being
interrupted. Since the Framework team already figured out how to
protect static ctors and catch/finally blocks that should be possible.
>No, for me rule to remember is "Never initiate asynchronous thread aborts in
>Framework code, unless it's part of an AD unload", there are more secure
>alternatives to stop a thread from making progress.
But not asynchronously, which is the point. With any alternative
method, the thread that is to be stopped must actively check for some
kind of signal. That may be very difficult to implement if your
thread is doing some complex and lengthy computation.
--
http://www.kynosarges.de
.
- Follow-Ups:
- Re: Thread.Abort [LONG]
- From: Willy Denoyette [MVP]
- Re: Thread.Abort [LONG]
- References:
- Thread.Abort
- From: Urs Vogel
- Re: Thread.Abort
- From: Willy Denoyette [MVP]
- Re: Thread.Abort
- From: Christoph Nahr
- Re: Thread.Abort
- From: Willy Denoyette [MVP]
- Re: Thread.Abort
- From: Christoph Nahr
- Re: Thread.Abort [LONG]
- From: Willy Denoyette [MVP]
- Re: Thread.Abort [LONG]
- From: Christoph Nahr
- Re: Thread.Abort [LONG]
- From: Willy Denoyette [MVP]
- Thread.Abort
- Prev by Date: Re: French Encoding
- Next by Date: RE: How to check a string
- Previous by thread: Re: Thread.Abort [LONG]
- Next by thread: Re: Thread.Abort [LONG]
- Index(es):
Relevant Pages
|
Loading