Ok, seems like we are getting nowhere here, so I'll try again.
1.I now (and I never suggested this) that "explicitly" calling Thread.Abort
is evil and should only be done "explicitly" when you are going to pull down
the AD in which the thread is running, but when you call Unload() it always
implies a ThreadAbort exception injected by the CLR, or do you mean that
calling Unload should never be done?
Note also that cleaning up your invariants makes little or no sense or AD
unloads (and in case of ThreadAbort; see 1.), the offending AD and all types
loaded in it will be thrown away when done.
2. The OP said he called AD Unload() he did not say he called Thread.Abort()
why would he?, and it took 30 seconds before the call return, that means
that the injected AbortException was not honored within the time-out (30
sec.)period the CLR waits to stop the threads in the offending AD
So the CLR starts a rude abort of the threads in the AD and unloads the
assemblies loaded and cleans-up the AD administration effectively removing
the AD. The fact that the Unload() call times-out makes me think that the
thread is running in unmanaged land (COM or PInvoke..) for longer than 30
seconds, another possibility is he spins in managed code or calls Sleep(>30
seconds), but this would surprise me (should ring a bell for the OP isn't?).
Anyway 'preparing' for such situation like you suggest makes no sense, the
thread is, or,
- 'unmanaged' and can only be stopped by a rude abort, or,
- he is spinning, sleeping or whatever can be done to ignore a
ThreadAbortException in managed code, in which way it's obvious for the
author why it's taking 30 seconds to unload the AD and act accordingly.
The only thing the OP can do is make sure that the thread returns in a
timely fashion in case of a AD unload, that is make sure you don't block in
COM (watch the blocking finalizer thread) or other unmanaged code. If you
need to call into unmanaged and this call is blocking, make sure you can
unblock the thread (for instance close the underlying socket in case of
blocking socket calls in your catch handler), if you can't prevent blocking,
you'll have to accept this 30 seconds delay and the rude abort.
Willy.
"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote in
message news:eI***************@tk2msftngp13.phx.gbl...
| Willy,
|
| You should re-read my previous post. I stated that if you know a
| Thread.Abort (or something that will trigger a Thread.Abort) is going to
be
| performed, then you really should clean up the state of your threads that
| will be affected beforehand.
|
| You are asking what to do in a specific instance which really has
| nothing to do with the question at hand. If a thread is in the middle of
a
| call to unmanaged code, then calling Unload on the AppDomain that the
thread
| is in is not going to stop the call.
|
| In a general sense, though, you have to have something that manages
this
| process for you. You have to have an object that ^knows^ about what is
| going on in that app domain, so that it can shut down properly. A call to
| Abort is messy, and irresponsible, and should never be done. To just do
so
| indiscriminately is a sign of poor design.
|
| --
| - Nicholas Paldino [.NET/C# MVP]
| -
mv*@spam.guard.caspershouse.com
|
| "Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
| news:O7**************@TK2MSFTNGP12.phx.gbl...
| >
| > Say an AD AD#1 creates an AD#2 that loads an assembly and starts running
| > code in it, this AD#2 starts creating threads that transition into
| > unmanaged
| > code and block, now I want to unload the assembly so I have to unload
the
| > AD#2, please tell me how are you gonna tell the threads in AD#2 to
'exit'
| > from AD#1?
| >
| > Willy.
| >
| >
| > "Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote
| > in
| > message news:ut**************@TK2MSFTNGP09.phx.gbl...
| > | Willy,
| > |
| > | The point that you missed in my response is that one shouldn't just
| > shut
| > | down app domains indiscriminately. If he can clean up threads, then
by
| > all
| > | means, he should do so. Since he knows that Unload is going to abort
| > his
| > | threads, he should take measures to exit those threads before he calls
| > | Unload.
| > |
| > | Since calling Unload on the AppDomain effectively calls
Thread.Abort
| > on
| > | any threads in the app domain, and I believe in my earlier statement
| > about
| > | RARELY having a good reason to call Thread.Abort, I'm saying that if
you
| > can
| > | clean up the thread(s) before a call to Unload, then do it.
| > |
| > | --
| > | - Nicholas Paldino [.NET/C# MVP]
| > | -
mv*@spam.guard.caspershouse.com
| > |
| > | "Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
| > | news:um**************@tk2msftngp13.phx.gbl...
| > | > The OP didn't say HE calls Thread.Abort(), he said ....
| > AppDomain.UnLoad
| > | > method (which calls the Thread.Abort....
| > | > There is nothing you can do about this, it's the way Unload is
| > | > implemented.
| > | > If you are loading assemblies in auxiliary AD's, you'll have to code
| > | > accordingly and watch for rude aborts introduced by the CLR.
| > | >
| > | >
| > | > Willy.
| > | >
| > | > "Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com>
| > wrote
| > | > in
| > | > message news:%2****************@TK2MSFTNGP12.phx.gbl...
| > | > | I didn't imply that it didn't. What I am saying is that
aborting
| > a
| > | > | thread is really bad practice, and can leave a system in an
| > inconsistent
| > | > | state.
| > | > |
| > | > | I can't think of a situation where a call to Abort on a thread
is
| > | > | justified.
| > | > |
| > | > |
| > | > | --
| > | > | - Nicholas Paldino [.NET/C# MVP]
| > | > | -
mv*@spam.guard.caspershouse.com
| > | > |
| > | > | "Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in
| > message
| > | > | news:eq**************@TK2MSFTNGP11.phx.gbl...
| > | > | > Abort() is called intrinsically by Unload().
| > | > | >
| > | > | > Willy.
| > | > | >
| > | > | >
| > | > | >
| > | > | > "Nicholas Paldino [.NET/C# MVP]"
<mv*@spam.guard.caspershouse.com>
| > | > wrote
| > | > | > in
| > | > | > message news:uu*************@TK2MSFTNGP15.phx.gbl...
| > | > | > | JPSuitor,
| > | > | > |
| > | > | > | Well, the error is pretty clear. What is it that thread is
| > doing
| > | > | > which
| > | > | > | is taking so long?
| > | > | > |
| > | > | > | You shouldn't rely on such an abrupt shutdown. Rather, you
| > | > should
| > | > | > | signal threads that you know are running in that app domain to
| > shut
| > | > | > down,
| > | > | > | and then call Unload.
| > | > | > |
| > | > | > | Hope this helps.
| > | > | > |
| > | > | > |
| > | > | > | --
| > | > | > | - Nicholas Paldino [.NET/C# MVP]
| > | > | > | -
mv*@spam.guard.caspershouse.com
| > | > | > |
| > | > | > | "JPSutor" <jp*****@yahoo.com> wrote in message
| > | > | > | news:11**********************@f14g2000cwb.googlegr oups.com...
| > | > | > | > when I use the AppDomain.UnLoad method (which calls the
| > | > Thread.Abort
| > | > | > | > method), I get the following error message
| > | > | > | >
| > | > | > | > AppDomain can not be unloaded because the thread 1378 can
not
| > be
| > | > | > | > unwound out of it
| > | > | > | >
| > | > | > | > It seems to take time doing this. If I wait for about 30
| > seconds,
| > | > it
| > | > | > | > seems to get unloaded.
| > | > | > | > Any ideas?
| > | > | > | >
| > | > | > |
| > | > | > |
| > | > | >
| > | > | >
| > | > |
| > | > |
| > | >
| > | >
| > |
| > |
| >
| >
|
|