|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Thread Abort and Unhandled Exception EventIn .NET 2.0 unhandled exceptions in separate threads cause raising unhandled exception event and terminating the process. This is true for most exceptions, but not for ThreadAbortException, what is reasonable. I have verified this with following example: class Program { private static void thread() { while (true){} } static void Main(string[] args) { AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(handler); Thread th = new Thread(new ThreadStart(thread)) th.Start(); Thread.Sleep(5000); th.Abort(); Thread.Sleep(50000); } static void handler(object sender, UnhandledExceptionEventArgs e) { System.Console.WriteLine("Unhandled exception."); } } While working with my, quite complex, application, where I must use Thread.Abort() on one of my threads, I managed to get in the handler following exception: Exception: System.Threading.ThreadAbortException Message: Thread was being aborted. Source: mscorlib at System.Reflection.Assembly.GetType(String name, Boolean throwOnError, Boolean ignoreCase) at System.Activator.CreateInstanceFrom(String assemblyFile, String typeName, Boolean ignoreCase, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, Evidence securityInfo) at System.AppDomain.CreateInstanceFrom(String assemblyFile, String typeName) The application terminated immediately because of that. This convinced me that in some circumstances ThreadAbortException is treated just as any other exception and can cause process crash in .NET 2.0. The above stack trace is a full stack trace which the exception conveyed, and looks bit strange for me. My code never use System.AppDomain.CreateInstanceFrom(..) directly, so I guess this is some internal mechanism of the framwork/CLR. Can you think what kind of my code can trigger above one ? It looks like something related to reflection. What is exact reason that the ThreadAbortException is not treated just as ThreadAbortException in my example. Generally this is very bad news for everyone who use Thread.Abort(), because there are poor guarantees that the operation does not crash their application. PS. Do not suggest me using a flag to stop a thread. Hello pawel.kedz***@gmail.com,
> In .NET 2.0 unhandled exceptions in separate threads cause raising The ThreadAbortException is asyn exception and can interrupt the target thread > unhandled exception event and terminating the process. This is true > for most exceptions, but not for ThreadAbortException, what is > reasonable. at any point > While working with my, quite complex, application, where I must use It's the well known that Thread.Abort is evil and your need to use other > Thread.Abort() on one of my threads, I managed to get in the handler > following exception: ways to interrupt your thread gracefully > This convinced me that in some circumstances ThreadAbortException is Yep, as async exceptions> treated just as any other exception and can cause process crash > in .NET 2.0. > Can you think what kind of my code can trigger above one ? It looks Because it can be arrised at any point, and not where you expect it> like something related to reflection. What is exact reason that the > ThreadAbortException is not treated just as ThreadAbortException in my > example. > Generally this is very bad news for everyone who use Thread.Abort(), Yep, it is.> because there are poor guarantees that the operation does not crash > their application. > PS. Do not suggest me using a flag to stop a thread. I recommend you to read this http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellationand this http://www.dotnetconsult.co.uk/weblog/PermaLink.aspx/4f52c396-1b0d-4419-8871-6ca6992460ca --- WBR, Michael Nemtsev [.NET/C# MVP]. My blog: http://spaces.live.com/laflour Team blog: http://devkids.blogspot.com/ "The greatest danger for most of us is not that our aim is too high and we miss it, but that it is too low and we reach it" (c) Michelangelo Hi Michael
Thank you for your response, but this still does not explain a few things. I agree that async exception can emerge in any location, I can not predict location in my code where does it happen, but I should be able to assume that stack trace of the exception will have at its bottom initial frame of my thread. The stack trace which I handled doesn't have such, it has only some .net framwork methods, see my first post. Also, I still claim that ThreadAbortException should not cause application crash directly by it self (by the fact that it was not caught - and moreover was not suppressed by Thread.ResetAbort()). Of course it may crash the application indirectly, because of changed flow, but anyway not ThreadAbortException should by received by unhandled exceptions event. zuraff pawel.kedz***@gmail.com wrote:
Show quote > Hi The ThreadAbortException is used to abort the thread while giving the > > In .NET 2.0 unhandled exceptions in separate threads cause raising > unhandled exception event and terminating the process. This is true > for most exceptions, but not for ThreadAbortException, what is > reasonable. > > I have verified this with following example: > class Program { > private static void thread() { > while (true){} > } > static void Main(string[] args) { > AppDomain.CurrentDomain.UnhandledException > += new UnhandledExceptionEventHandler(handler); > Thread th = new Thread(new ThreadStart(thread)) > th.Start(); > Thread.Sleep(5000); > th.Abort(); > Thread.Sleep(50000); > } > > static void handler(object sender, UnhandledExceptionEventArgs > e) { > System.Console.WriteLine("Unhandled exception."); > } > } > > While working with my, quite complex, application, where I must use > Thread.Abort() on one of my threads, I managed to get in the handler > following exception: > > Exception: System.Threading.ThreadAbortException > Message: Thread was being aborted. > Source: mscorlib > at System.Reflection.Assembly.GetType(String name, Boolean > throwOnError, Boolean ignoreCase) > at System.Activator.CreateInstanceFrom(String assemblyFile, String > typeName, Boolean ignoreCase, > BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo > culture, Object[] > activationAttributes, Evidence securityInfo) > at System.AppDomain.CreateInstanceFrom(String assemblyFile, String > typeName) > > The application terminated immediately because of that. > > This convinced me that in some circumstances ThreadAbortException is > treated just as any other exception and can cause process crash > in .NET 2.0. > The above stack trace is a full stack trace which the exception > conveyed, and looks bit strange for me. My code never use > System.AppDomain.CreateInstanceFrom(..) directly, so I guess this is > some internal mechanism of the framwork/CLR. > > Can you think what kind of my code can trigger above one ? It looks > like something related to reflection. What is exact reason that the > ThreadAbortException is not treated just as ThreadAbortException in my > example. > > Generally this is very bad news for everyone who use Thread.Abort(), > because there are poor guarantees that the operation does not crash > their application. > > PS. Do not suggest me using a flag to stop a thread. > thread an opportunity to clean up critical data. The thread should catch the ThreadAbortException, do any neccesary cleanup, and return from the method. If possible, Thread.Abort should be avoided. As it stops the thread whatever if might be doing, it might be difficult to write the cleanup code so that it can properly handle every possible state that the code can be in. Thanks Goran
What you says is clear to me. However I'm looking for the answer for following question: When ThreadAbortException, when it reaches bottom of stack trace of its thread causes AppDomain.UnhandledException event and terminating the application ? I don't mind illegal state of my code, because of change of the flow due to Thread.Abort(). On Wed, 18 Apr 2007 11:29:19 -0700, <pawel.kedz***@gmail.com> wrote:
> However I'm looking for the answer for following question: When I think you misunderstand the nature of "UnhandledException". It's an > ThreadAbortException, when it reaches bottom of stack trace of its > thread causes AppDomain.UnhandledException event and terminating the > application ? event, not an exception handler. This has two important implications: 1) It's not running in the thread where the exception occured. That is, it doesn't "reach the bottom of stack trace of its thread". The thread has no handler for the exception, and so the thread crashes. 2) It's not *handling* the exception. It's simply giving you notice that an unhandled exception occurred. This may or may not be a problem for you, but the fact remains that the exception wasn't ever handled and if not handling the exception results in instability your entire process may indeed crash. If you insist on using Thread.Abort(), then you need to put an exception handler in the thread itself (that is, try/catch at the top of the thread *and* make sure that you never abort the thread unless you are 100% certain that the thread is within the try block). Really, you should not be using Thread.Abort() at all. But if you insist on doing so, then you need to handle the exception if you expect for the exception to be handled properly. Pete Hi Pete
> I think you misunderstand the nature of "UnhandledException". It's an I might have called that a handler, but I never thought so. The key is> event, not an exception handler. that once the application is terminating, you can not cancel the process. > then you need to put an exception So what you suggest is to:> handler in the thread itself (that is, try/catch at the top of the thread > *and* make sure that you never abort the thread unless you are 100% > certain that the thread is within the try block). Thread th = new Thread(new ThreadStart(foo)); th.Start(); .... th.Abort(); .... public void foo() { try { ... } catch (Exception e) {...} } I understand that you claim that the catch block will prevent from slipping ThreadAbortException outside foo() if only Abort was called within try/catch. That is not actually true, because ThreadAbortException will be rethrown automatically after leaving catch{} block, provided that Thread.ResetAbort() was not called before. But usually, e.g. in my example in the first post, it is okey. CLR just suppresses that type of exceptions once they slip out of the thread and process is not terminated. Nothing bad happens. But for some reason, which I need to discover, some time CLR does not suppress it and the process IS terminated. Moreover the stack trace which I managed to log in that case (see my first post) using UnhandledException event, does not consist my code, and doesn't give me any chance to add try/catch(){ Thread.ResetAbort();} which will prevent from slipping it outside. On Wed, 18 Apr 2007 12:55:46 -0700, <pawel.kedz***@gmail.com> wrote:
> [...] That's correct.> I understand that you claim that the catch block will prevent from > slipping ThreadAbortException outside foo() if only Abort was called > within try/catch. > That is not actually true, because ThreadAbortException will be This statement has very little to do with the previous. I never suggested > rethrown automatically after leaving catch{} block, provided that > Thread.ResetAbort() was not called before. that including an exception handler would prevent the thread from being aborted. I am only pointing out that if you want to catch the exception, you have to have some code that it set up to catch exceptions. > [...] You can try to figure that issue out if you like. However, the > But for some reason, which I need to discover, some time CLR does not > suppress it and the process IS terminated. fundamental nature of what you're doing is so wrong in the first place, it's my opinion that what you really ought to be doing is fixing your design so that you don't rely on the behavior of Thread.Abort() in the first place. > Moreover the stack trace That suggests to me that by aborting your thread, you are somehow screwing > which I managed to log in that case (see my first post) using > UnhandledException event, does not consist my code, and doesn't give > me any chance to add try/catch(){ Thread.ResetAbort();} which will > prevent from slipping it outside. up some other thread. How that might happen, I don't know, and I can't rule out the possibility of a .NET bug. Still, since you're not exercising good thread-management behavior in the first place, it's hard to work up much interest in figuring out your problem for you. I realize you started out telling us all (in effect) to not tell you to not use Thread.Abort(). But really, that's the best advice anyone could give you. Pete |
|||||||||||||||||||||||