|
Thanks PIEBALDconsult,
Good reference.
regards,
George
|
|
|
|
|
Hi Spacix,
I doubt whether your approach could achieve the same effect as using Application.ThreadException or AppDomain.CurrentDomain.UnhandledException (suppose there are multple threads)? Any comments?
regards,
George
|
|
|
|
|
George_George wrote: Application.ThreadException is for Windows Form application, not console and Windows Service application?
I don't think that there is a method to do this on console applications. In windows applications, you can hook event handlers to Application.ThreadException or AppDomain.CurrentDomain.UnhandledException . But these event handlers won't be executed in all cases. If the exception is occurring before the event handler is hooked, it won't be handled. Also exceptions occurring in unmanaged resources won't be handled too.
|
|
|
|
|
Thanks N a v a n e e t h,
What do you mean "windows applications"? I have checked again in VS 2008, there is not a project type names "windows applications". Do you mean Windows Forms application?
regards,
George
|
|
|
|
|
George_George wrote: Windows Forms application?
Yes. Also you can wrap the main() method in try catch blocks. So it can handle all exceptions.
|
|
|
|
|
No, N a v a n e e t h. Not catch all exceptions, you can not catch exception from other threads? Right?
regards,
George
|
|
|
|
|
George_George wrote: you can not catch exception from other threads? Right?
Yes. You are right. I missed that. Hook AppDomain.UnhandledException which handles all exception other than the ones I specified in my first message.
|
|
|
|
|
You mean "Also exceptions occurring in unmanaged resources won't be handled too" will not be handled?
regards,
George
|
|
|
|
|
George_George wrote: "Also exceptions occurring in unmanaged resources won't be handled too"
Yes. It won't be handled. Because it runs out of CLR.
|
|
|
|
|
Thanks N a v a n e e t h,
1.
Seems UnhandledException is the only approach to handle exception from other threads, and I have tried even ProcessExit does not work. Here is my code to test. Could you review whether my code and my points are correct?
2.
After the handler for UnhandledException is executed, process is always terminated?
using System;
using System.Threading;
namespace DelegateThread
{
class Test
{
private static void Method2 (object input)
{
Console.WriteLine("Method1 is throwing exception");
throw new ApplicationException("**** oops ****");
}
private static void Method1()
{
Console.WriteLine("Method1 is throwing exception");
throw new ApplicationException("**** oops ****");
}
private static void Handler1 (object sender, EventArgs e)
{
Console.WriteLine ("I am here");
}
private static void Handler3(object sender, EventArgs e)
{
Console.WriteLine("I am here");
}
delegate void Method1Delegate();
static void Main(string[] args)
{
Console.WriteLine("We first use a thread");
AppDomain.CurrentDomain.ProcessExit += new EventHandler (Test.Handler1);
AppDomain.CurrentDomain.UnhandledException +=new UnhandledExceptionEventHandler(Test.Handler3);
Thread aThread
= new Thread(new ThreadStart(Method1));
aThread.Start();
Thread.Sleep(5000);
Console.WriteLine("Survived exception");
return;
}
}
}
regards,
George
|
|
|
|
|
George_George wrote: and I have tried even ProcessExit
ProcessExist is not needed here
George_George wrote: After the handler for UnhandledException is executed, process is always terminated?
mm, look like you are still not clear. I will try to explain once more. AppDomain.UnhandledException is not an exception handler like catch . It's an event which will be fired before program exits due to uncaught error. After handler is executed, process will be terminated. This is a new behavior from .NET 2.0 onwards. In handler you can do necessary steps to log the error. You can't prevent application ending. In that handler you can show friendly messages to user and inform him that we are closing.
Considering all these points in mind, your demo code is working as expected. Handler is getting executed and application is closing. You need to change the handler3() method like this.
private static void Handler3(object sender, UnhandledExceptionEventArgs e)
{
Exception exceptionOccured = e.ExceptionObject as Exception;
string errorMessage = exceptionOccured.Message;
Console.WriteLine("I am here");
}
. In this you can see how exception occurred is retrieved from the event argument. You can log the exception message and application will be exited gracefully.
.NET 1.1 behavior can be taken back by setting some flag value in application.config file. See this[^]. But I don't recommend that, as I don't know the pros/cons of that.
Hope it's clear now.
|
|
|
|
|
Thanks N a v a n e e t h,
Cool! I have made further tests that, there is one exception case. When exception is from thread pool thread -- but in the situation of executing asynchronous method call, we can catch the exception (even if unhandled in the thread pool worker thread) in EndInvoke in main thread.
So, here is a case when there is unhandled exception in another thread, we can still catch it and not make process terminated.
Any comments?
regards,
George
|
|
|
|
|
George_George wrote: but in the situation of executing asynchronous method call, we can catch the exception (even if unhandled in the thread pool worker thread) in EndInvoke in main thread.
This how asynchronous methods works. It will handle exception safely and throws when end method is called.
George_George wrote: when there is unhandled exception in another thread, we can still catch it and not make process terminated.
You are always allowed to catch exceptions in the same thread. Cross-thread exception handling is only not possible. In this case also you are handling exceptions in the same thread, so there won't be any issues. Asynchronous method runs on a thread pool thread and handles exception inside that method and keep it until end is called. When end is called, it will check exception is null, if not null it will be thrown.
|
|
|
|
|
Thanks N a v a n e e t h,
So, asynchronous function call is the only case when we can catch exception from another thread?
regards,
George
|
|
|
|
|
George_George wrote: So, asynchronous function call is the only case when we can catch exception from another thread?
George, we are not able to catch exceptions happening on another thread. In this case also it's not happening. We are catching exception in the asynchronous method it self and keeping it for future use. When end method is called, this exception will be thrown out. Have a look at the following code
Exception raisedException = null;
void BeginRead()
{
try{
}
cath(Exception ex){
raisedException = ex;
}
}
void EndRead()
{
if(raisedException != null) throw raisedException;
} In the above code, we have handled the exception and threw it when end is called. Note we handled the exception in the same thread where asynchronous method is executing, not in the main thread.
Hope things are clear now.
|
|
|
|
|
Thanks N a v a n e e t h,
I agree with all of your points, except this one,
N a v a n e e t h wrote: Note we handled the exception in the same thread where asynchronous method is executing, not in the main thread.
My point is we should handle it in main thread. Here is my code to prove. Any comments?
(sorry the code is a little messy, I used it to test for multi-purpose in this discussion.)
using System;
using System.Threading;
namespace DelegateThread
{
class Test
{
private static void Method2 (object input)
{
Console.WriteLine("Method1 is throwing exception");
throw new ApplicationException("**** oops ****");
}
private static void Method1()
{
Console.WriteLine("Method1 is throwing exception");
throw new ApplicationException("**** oops ****");
}
private static void Handler1 (object sender, EventArgs e)
{
Console.WriteLine ("I am here");
}
private static void Handler3(object sender, EventArgs e)
{
Console.WriteLine("I am here");
}
delegate void Method1Delegate();
static void Main(string[] args)
{
Console.WriteLine("We first use a thread");
Console.WriteLine("We will use a Delegate now");
Method1Delegate dlg = new Method1Delegate(Method1);
IAsyncResult handle = dlg.BeginInvoke(null, null);
Thread.Sleep(1000);
Console.WriteLine("Was the exception reported so far?");
try
{
Console.WriteLine("Let's call EndInvoke");
dlg.EndInvoke(handle);
}
catch (Exception ex)
{
Console.WriteLine("Exception: {0}", ex.Message);
}
Thread.Sleep(5000);
Console.WriteLine("Survived exception");
return;
}
}
}
regards,
George
|
|
|
|
|
George_George wrote: My point is we should handle it in main thread. Here is my code to prove. Any comments?
Your code is working perfectly. I guess you tried it by running the application in debug mode - Right ? When application runs on debug mode, VS editor will break when exception occurs and points to the suspected line. You should try running this without in debug mode (Ctrl + F5). You can see it executes correctly. Exception will be caught when EndInvoke() get called.
|
|
|
|
|
Thanks for your review, N a v a n e e t h!
It is clear now.
regards,
George
|
|
|
|
|
For a console app, you could put try/catch around the guts of your main() function.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
Hi John,
I think in this approach, we can only catch exception from main thread, right?
(Suppose we create new threads from main methods, then we can not catch exception from other threads in main method?)
regards,
George
|
|
|
|
|
If you wanted to go that far you can catch errors in your thread method also...
Are you looking for on error resume next type functionally? If so might be better to use VB.NET as C# doesn't allow for that coding horror
You need to remember the following:
Using exceptions to control programming logic is is the same as having car insurance to repair the damange after rolling off a cliff instead of setting the parking break to prevent it from rolling away.
|
|
|
|
|
Thanks Spacix,
1.
Spacix One wrote: If you wanted to go that far you can catch errors in your thread method also...
So, no means to catch exception from another thread, right?
2.
Spacix One wrote: on error resume next type functionally? If so might be better to use VB.NET as C# doesn't allow for that coding horror
Sorry, I have no experience in VB. Could you say something alternative to describe your ideas please? I do not quite understand, especially what do you mean "on error resume next type functionally".
regards,
George
|
|
|
|
|
George_George wrote: I do not quite understand, especially what do you mean "on error resume next type functionally".
It's a VB syntax used to resume the processing on errors. If on error resume next is provided on the code, errors will be skipped. Keep it in mind, this is for VB/VB.NET and not for C#.
|
|
|
|
|
Thanks for clarification, N a v a n e e t h!
regards,
George
|
|
|
|
|
N a v a n e e t h answered #2
As for number one you can catch them in that thread, example:
System.Threading.Thread mythread = new System.Threading.Thread
(delegate()
{
try
{
throw new Exception("Oh no, my thread crashed!");
}
catch(Exception err)
{
File.WriteAllText(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\error.log",
DateTime.Now.ToString() + Environment.NewLine + err.ToString() + Environment.NewLine + Environment.NewLine);
}
});
mythread.Start();
|
|
|
|