471,319 Members | 1,750 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,319 software developers and data experts.

AppDomain closing ?

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?

Jan 9 '06 #1
22 3623
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?

Jan 9 '06 #2
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?
| >
|
|
Jan 9 '06 #3

"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?
|

The CLR will orce a rude abort when a Thread.Abort() times out. This is the
CLR's normal behavior, the system can't wait forever for an AD unload. Your
issue is that your thread runs or is blocked in unmanaged code, all you can
do is resume this blocking thread or make sure threads don't stay that long
in unmanaged code.

Willy.
Jan 9 '06 #4
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?
| >
|
|

Jan 9 '06 #5
Try using Thread.Join after signaling threads you want to terminate, then on
return call AppDomain.Unload().

Cheers
Simon.

"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?

Jan 9 '06 #6
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?
| > | >
| > |
| > |
| >
| >
|
|
Jan 9 '06 #7
Thread.Join isn't of any help when unloading an AD which has threads that
stay running or blocking for a long period in "unmanaged land".
Willy.

"Simon Hart" <srhartone@[no spam]yahoo.com> wrote in message
news:Ob**************@TK2MSFTNGP09.phx.gbl...
| Try using Thread.Join after signaling threads you want to terminate, then
on
| return call AppDomain.Unload().
|
| Cheers
| Simon.
|
| "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?
| >
|
|
Jan 9 '06 #8
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?
| > | >
| > |
| > |
| >
| >
|
|

Jan 9 '06 #9
He didn't state that his threads were in "unmanaged land" did he.

"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
news:%2***************@TK2MSFTNGP15.phx.gbl...
Thread.Join isn't of any help when unloading an AD which has threads that
stay running or blocking for a long period in "unmanaged land".
Willy.

"Simon Hart" <srhartone@[no spam]yahoo.com> wrote in message
news:Ob**************@TK2MSFTNGP09.phx.gbl...
| Try using Thread.Join after signaling threads you want to terminate,
then
on
| return call AppDomain.Unload().
|
| Cheers
| Simon.
|
| "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?
| >
|
|

Jan 9 '06 #10
Absolutely, theres no telling what is happening with those threads with an
abrupt abort.

"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?
| > | >
| > |
| > |
| >
| >
|
|


Jan 9 '06 #11

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?
| > | > | >
| > | > |
| > | > |
| > | >
| > | >
| > |
| > |
| >
| >
|
|
Jan 9 '06 #12
Tell me then why the Thread.Abort implied by AD Unload did not return
immidiately, two possible answers here: the thread is blocked in unmanaged
code, or the thread catches the ThreadAbort exception and starts spinning or
sleeping, tell me, what's the most obvious?
Also don't forget that the CLR escalates a Thread.Abort to a rude abort
after waiting for 30 seconds.

Willy.
"Simon Hart" <srhartone@[no spam]yahoo.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
| He didn't state that his threads were in "unmanaged land" did he.
|
| "Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
| news:%2***************@TK2MSFTNGP15.phx.gbl...
| > Thread.Join isn't of any help when unloading an AD which has threads
that
| > stay running or blocking for a long period in "unmanaged land".
| >
| >
| > Willy.
| >
| > "Simon Hart" <srhartone@[no spam]yahoo.com> wrote in message
| > news:Ob**************@TK2MSFTNGP09.phx.gbl...
| > | Try using Thread.Join after signaling threads you want to terminate,
| > then
| > on
| > | return call AppDomain.Unload().
| > |
| > | Cheers
| > | Simon.
| > |
| > | "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?
| > | >
| > |
| > |
| >
| >
|
|
Jan 9 '06 #13
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?
| > | > | >
| > | > |
| > | > |
| > | >
| > | >
| > |
| > |
| >
| >
|
|

Jan 9 '06 #14
I should refine my statement about the call to Unload not cancelling the
call to unmanaged code to mean that initially. Yes, a rude abort will be
performed, but that's not a good situation either.
--
- 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?
| > | > | >
| > | > |
| > | > |
| > | >
| > | >
| > |
| > |
| >
| >
|
|

Jan 9 '06 #15
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?
| > | > | > | >
| > | > | > |
| > | > | > |
| > | > | >
| > | > | >
| > | > |
| > | > |
| > | >
| > | >
| > |
| > |
| >
| >
|
|
Jan 9 '06 #16
That's the result of a Domain Unload for a domain that has a thread running
in unmanaged code for a long period of time without returning to managed
code. Note that a lot of managed code can stay blocked in unmanaged land!
The only thing you can do about is to prevent this as much as possible, or
accept the Unload delay.

Willy.


"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote in
message news:uE**************@TK2MSFTNGP15.phx.gbl...
| I should refine my statement about the call to Unload not cancelling
the
| call to unmanaged code to mean that initially. Yes, a rude abort will be
| performed, but that's not a good situation either.
|
|
| --
| - 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?
| > | > | > | >
| > | > | > |
| > | > | > |
| > | > | >
| > | > | >
| > | > |
| > | > |
| > | >
| > | >
| > |
| > |
| >
| >
|
|
Jan 9 '06 #17

Hi guys,
You started on a good discussions but totally went off-tracks
after a while talking abount unmanaged threads.

I found this post looking for help in resolving that same
issue i have.

Reproducing the behaviour is pretty simple :

1 - Create a "child app" that does nothing.

2 - Create a master app. In that master app, create a class in wich you
create a new appdomain, and start a thread that simply calls
"newAppDomain.executeassembly". Also create a function that calls
"appdomain.unload(newappdomain)" .

3 - On the click of a button or form_load or wathever else, create 2-3
instances of the class, and call the function that unloads on one
class... you'll get the "Unable to unload" error.
No Locked threads in unmanaged code there !

I noticed that ExecuteAssembly is a locking function call.. could that
be the "locking" point wich cause the thread to be "locked" and can't
abort properly ?!
--
morgie
Message posted via http://www.exforsys.com for all your training needs.

Jan 17 '06 #18

"morgie" <mo***********@no-mx.forums.yourdomain.com.au> wrote in message
news:mo***********@no-mx.forums.yourdomain.com.au...
|
| Hi guys,
| You started on a good discussions but totally went off-tracks
| after a while talking abount unmanaged threads.
|
| I found this post looking for help in resolving that same
| issue i have.
|
| Reproducing the behaviour is pretty simple :
|
| 1 - Create a "child app" that does nothing.
|
| 2 - Create a master app. In that master app, create a class in wich you
| create a new appdomain, and start a thread that simply calls
| "newAppDomain.executeassembly". Also create a function that calls
| "appdomain.unload(newappdomain)" .
|
| 3 - On the click of a button or form_load or wathever else, create 2-3
| instances of the class, and call the function that unloads on one
| class... you'll get the "Unable to unload" error.
|
|
| No Locked threads in unmanaged code there !
|
|
|
| I noticed that ExecuteAssembly is a locking function call.. could that
| be the "locking" point wich cause the thread to be "locked" and can't
| abort properly ?!
|
|

All depends what you are doing in the entry point of the Assembly you have
loaded. ExecuteAssembly is not a blocking function call, it's just an
ordinary function call, that means as long as the function did not return,
you can't unload the AD which contains the Assembly.

Willy.

Jan 17 '06 #19

I managed to solve my problem this way :

in the clientApp , i handle the "appDomain.DomainUnload" event, and in
the handler function i simply call "me.close". That exits the
applications and "appdomian.unload" no longer returns the "unable to
unload appdomain..." error :)

Now , i have to figure out if it's possible... using the AppDomain
objects, to inform the "master" that a child has just left the ship :)
(Clicking on X on the child app for example)

Also, closing the Master app (the process starter) doesn't seems to
systematically force all other appdomains to kill so i guess i'll have
to loop on all the appDomain created to unload them.
--
morgie
Message posted via http://www.exforsys.com for all your training needs.

Jan 17 '06 #20

"morgie" <mo***********@no-mx.forums.yourdomain.com.au> wrote in message
news:mo***********@no-mx.forums.yourdomain.com.au...
|
| I managed to solve my problem this way :
|
| in the clientApp , i handle the "appDomain.DomainUnload" event, and in
| the handler function i simply call "me.close". That exits the
| applications and "appdomian.unload" no longer returns the "unable to
| unload appdomain..." error :)
|
| Now , i have to figure out if it's possible... using the AppDomain
| objects, to inform the "master" that a child has just left the ship :)
| (Clicking on X on the child app for example)
|
| Also, closing the Master app (the process starter) doesn't seems to
| systematically force all other appdomains to kill so i guess i'll have
| to loop on all the appDomain created to unload them.
|
|
| --
| morgie
| Message posted via http://www.exforsys.com for all your training needs.
|

I honnestly don't know what you mean by all this, sorry, but I don't think
this as anything to do with the originam subject.
Also me.close and client apps and master app doesn't say a thing. Seems like
you are loading full windows forms applications (.exe) in separate domains,
but this isn't really what AD's are designed for and you better don't use
this as it almost impossible to get it right.
Willy.
Jan 17 '06 #21

Sorry, you're right as i'm totally out of context.. I just wanted to
share an experience i got with the error mentionned in the first post,
and how I managed to solve it.

As for loading multiple windows apps into different AppDomains of a
single process, well that's not my decision, that's an avenue i was
asked to explore to increase performance of an MSDI (Multi-Single
Document Interface) model. But that's a complete other story as you
mentionned :)
--
morgie
Message posted via http://www.exforsys.com for all your training needs.

Jan 18 '06 #22

"morgie" <mo***********@no-mx.forums.yourdomain.com.au> wrote in message
news:mo***********@no-mx.forums.yourdomain.com.au...
|
| Sorry, you're right as i'm totally out of context.. I just wanted to
| share an experience i got with the error mentionned in the first post,
| and how I managed to solve it.
|
| As for loading multiple windows apps into different AppDomains of a
| single process, well that's not my decision, that's an avenue i was
| asked to explore to increase performance of an MSDI (Multi-Single
| Document Interface) model. But that's a complete other story as you
| mentionned :)
|
|

I see, I had the same experience, and learned by this, that AD's aren't that
valuable at all. They are 'usable" for add-in's but that's it, even in
asp.net it's better to use the IIS6 multi process application model than to
rely on AD's, of course you need W2K3 for this.

Willy.
Jan 18 '06 #23

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by JJ | last post: by
4 posts views Thread by Chris Lacey | last post: by
4 posts views Thread by illegal.prime | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.