Pattern for implementing sync methods in terms of non-parallel Task (Translating/Unwrapping AggregateExceptions)

前端 未结 1 994
难免孤独
难免孤独 2021-01-03 00:04

I have an Async method returning a Task.

I also wish to offer a synchronous equivalent, but I don\'t want consumers of it to have to go unpacking AggregateExce

相关标签:
1条回答
  • 2021-01-03 00:19

    There's no "clean" way to do this that I know of. You can't use throw someInnerException; because you'll lose the stack wherever the exception originated in the the async workflow and if you just use throw; you're obviously going to propagate the AggregateException. What you would have to do for the synchronous method is have some kind of "wrapper" exception that you can stuff the first exception of the AggregateException into and then throw that consistently from the synchronous version of the method.

    void Call()
    {
        try
        {
            CallAsync().Wait();
        }
        catch (AggregateException ex)
        {
            throw new MyConsistentWrapperException("An exception occurred while executing my workflow. Check the inner exception for more details.", ex.Flatten().InnerExceptions.First());
        }
    }
    

    FWIW, they've solved this in 4.5 with the new ExceptionDispatchInfo class which will help you marshal exceptions across threads without whacking the stack. Then you could write the synchronous version like this:

    void Call()
    {
        try
        {
            CallAsync().Wait();
        }
        catch (AggregateException ex)
        {
            ExceptionDispatchInfo.Capture(ex.Flatten().InnerExceptions.First()).Throw();
        }
    }
    
    0 讨论(0)
提交回复
热议问题