Catching an exception thrown in an asynchronous callback

后端 未结 3 592
日久生厌
日久生厌 2021-01-04 23:10

I have a method that takes a callback argument to execute asynchronously, but the catch block doesn\'t seem to be catching any exceptions thrown by the synchronous call (

相关标签:
3条回答
  • 2021-01-04 23:32

    If you're targeting .NET 4.0, you can utilize the new Task Parallel Library, and observe the Task object's Exception property.

    public Task Submit(FileInfo file)
    {
        return Task.Factory.StartNew(() => DoSomething(file));
    }
    
    private void DoSomething(FileInfo file)
    {
        throw new Exception();
    }
    

    Then use it like this:

    Submit(myFileInfo).ContinueWith(task =>
    {
        // Check task.Exception for any exceptions.
    
        // Do stuff with task.Result
    });
    

    where DoSomething is the method you'd like call asynchronously, and the delegate you pass to ContinueWith is your callback.

    More information about exception handling in TPL can be found here: http://msdn.microsoft.com/en-us/library/dd997415.aspx

    0 讨论(0)
  • 2021-01-04 23:34

    This is not a 'best practice' solution, but I think it's a simple one that should work.

    Instead of having the delegate defined as

    private delegate string SubmitFileDelegate(FileInfo file);
    

    define it as

    private delegate SubmitFileResult SubmitFileDelegate(FileInfo file);
    

    and define the SubmitFileResult as follows:

    public class SubmitFileResult
    {
        public string Result;
        public Exception Exception;
    }
    

    Then, the method that actually does the file submission (not shown in the question) should be defined like this:

    private static SubmitFileResult Submit(FileInfo file)
    {
        try
        {
            var submissionResult = ComplexSubmitFileMethod();
    
            return new SubmitFileResult { Result = submissionResult };
        }
        catch (Exception ex)
        {
            return new SubmitFileResult {Exception = ex, Result = "ERROR"};
        }
    }
    

    This way, you'll examine the result object, see if it has the Result or the Exception field set, and act accordingly.

    0 讨论(0)
  • 2021-01-04 23:37

    In short, no.

    When you call submitDelegate.BeginInvoke, it spawns the new thread, returns, and promptly exits your try/catch block (while the new thread runs in the background).

    You could, however, catch all unhandled exceptions like this:

    AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(YourException);

    This will catch everything in the application domain, however (not just your async method).

    0 讨论(0)
提交回复
热议问题