Re: Thread.Abort [LONG]



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
.



Relevant Pages

  • Re: [RFC] Resource Management - Infrastructure choices
    ... VServer) and resource management requirements? ... hanging off each container structure). ... do the same thing in any other resource controller. ... set a task's beancounter id. ...
    (Linux-Kernel)
  • Re: [RFC][PATCH 1/7] Resource counters
    ... Each resource accounting container is supposed to ... Is there any way to indicate that there are no limits on this container. ... return ret; ...
    (Linux-Kernel)
  • Re: [RFC][PATCH 1/7] Resource counters
    ... Each resource accounting container is supposed to ... Is there any way to indicate that there are no limits on this container. ... return ret; ...
    (Linux-Kernel)
  • Re: [ckrm-tech] [RFC] Resource Management - Infrastructure choices
    ... Browsers like firefox/lynx go into the WWW network class, ... If we had the ability to write pids directly to these resource classes, ... he now would have to create a separate container for ... resource node as its parent or a freshly child node of the parent ...
    (Linux-Kernel)
  • Re: a question about "unadvise" and leaks
    ... Sorry for interrupting in the middle of this thread, ... titled "changing from Hebrew to English using alt_shift in explorer" ... I have the same problem and cant find any other resource on the net to ...
    (microsoft.public.inetsdk.programming.webbrowser_ctl)

Loading