locked
Async Delegate Exception - Cannot catch RRS feed

  • Question

  • User2090782264 posted

    I have the following .NET page below. I'm trying to catch the exception in the AsyncResult method but it keeps throwing the SomeMethod exception?!?!?


    public class TestPage : Page { public delegate void MyMethod(); public void SomeMethod() { throw new Exception("error"); // this is thrown instead of being catched in the AsyncResult method } public void MyMethod_AsyncResult(IAsyncResult ar) { MyMethod method = (MyMethod)((AsyncResult)ar).AsyncDelegate try { method.EndInvoke(ar); } catch (Exception e) { throw new Exception("error was caught"); } } public void Page_Load(object sender, EventArgs e) { MyMethod method = new MyMethod(SomeMethod); method.BeginInvoke(MyMethod_AsyncResult, null); } }


    Thursday, December 31, 2009 11:31 AM

Answers

  • User-952121411 posted

    I think the issue is arising because you are calling the 'EndInvoke' method from the delegate method rather than from the original Page_Load() method where you invoked the async delegate.  It is correct in that you do need to call the EndInvoke in order to catch exceptions, or otherwise they would be discarded, but I think it may need to be called in Page_Load(). 

    The following page has a sample and situation similar to yours; they poll while the main thread works, and then calls the 'EndInvoke' after the main thread has completed processing.  You may want to test it in this manner as well to see if you can get the expected resutls:

    Exception Handling Thrown from an Asynchronous Delegate:

    http://codeidol.com/csharp/csharpckbk2/Exception-Handling/Handling-Exceptions-Thrown-from-an-Asynchronous-Delegate/

    Here is an excerpt from the above that details the situation:

    "If the code in the PollAsyncDelegate method did not contain a call to the delegate's EndInvoke method, the exception thrown in Method1 either would simply be discarded and never caught or, if the application had the top, level exception handlers wired up (Recipes 7.10 and 7.20) it would be caught. If EndInvoke is called, then this exception would occur when EndInvoke is called and could be caught there. This behavior is by design; for all unhandled exceptions that occur within the thread, the thread immediately returns to the thread pool and the exception is lost.

    If a method that was called asyncresultshronously through a delegate throws an exception, the only way to trap that exception is to include a call to the delegate's EndInvoke method and wrap this call in an exception handler. The EndInvoke method must be called to retrieve the results of the asynchronous delegate; in fact, the EndInvoke method must be called even if there are no results. These results can be obtained through a return value or any ref or out parameters of the delegate."

    There is also a good example of calling the EndInvoke method properly if you scroll to the 2nd code example in the following MSDN link:

    Calling Synchronous Methods Asynchronously (Waiting for an Asynchronous Call with EndInvoke):

    http://msdn.microsoft.com/en-us/library/2e08f6yc.aspx

    Hope this helps! Smile

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, January 4, 2010 4:01 PM

All replies

  • User187056398 posted

    That's an interesting problem.

    I think what is happening is that the delegated function is running in a different thread so when the exception is raised, it isn't in the call stack of the calling thread so it is caught and forwarded to the MyMethod_AsyncResult function.

    You try to handle it in MyMethod_AsyncResult but that function is still in the delegated function's thread.  So when you throw another exception, it still isn't in the main thread and it's forwarded again to the MyMethod_AsyncResult function.

    You'll need to change the way the function reports errors so both threads have access to the information.

     

    Thursday, December 31, 2009 12:48 PM
  • User-952121411 posted

    I think the issue is arising because you are calling the 'EndInvoke' method from the delegate method rather than from the original Page_Load() method where you invoked the async delegate.  It is correct in that you do need to call the EndInvoke in order to catch exceptions, or otherwise they would be discarded, but I think it may need to be called in Page_Load(). 

    The following page has a sample and situation similar to yours; they poll while the main thread works, and then calls the 'EndInvoke' after the main thread has completed processing.  You may want to test it in this manner as well to see if you can get the expected resutls:

    Exception Handling Thrown from an Asynchronous Delegate:

    http://codeidol.com/csharp/csharpckbk2/Exception-Handling/Handling-Exceptions-Thrown-from-an-Asynchronous-Delegate/

    Here is an excerpt from the above that details the situation:

    "If the code in the PollAsyncDelegate method did not contain a call to the delegate's EndInvoke method, the exception thrown in Method1 either would simply be discarded and never caught or, if the application had the top, level exception handlers wired up (Recipes 7.10 and 7.20) it would be caught. If EndInvoke is called, then this exception would occur when EndInvoke is called and could be caught there. This behavior is by design; for all unhandled exceptions that occur within the thread, the thread immediately returns to the thread pool and the exception is lost.

    If a method that was called asyncresultshronously through a delegate throws an exception, the only way to trap that exception is to include a call to the delegate's EndInvoke method and wrap this call in an exception handler. The EndInvoke method must be called to retrieve the results of the asynchronous delegate; in fact, the EndInvoke method must be called even if there are no results. These results can be obtained through a return value or any ref or out parameters of the delegate."

    There is also a good example of calling the EndInvoke method properly if you scroll to the 2nd code example in the following MSDN link:

    Calling Synchronous Methods Asynchronously (Waiting for an Asynchronous Call with EndInvoke):

    http://msdn.microsoft.com/en-us/library/2e08f6yc.aspx

    Hope this helps! Smile

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, January 4, 2010 4:01 PM