A good solution for await in try/catch/finally?

后端 未结 4 1725
南笙
南笙 2020-12-04 07:20

I need to call an async method in a catch block before throwing again the exception (with its stack trace) like this :

try
{
    //         


        
4条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-12-04 07:48

    We extracted hvd's great answer to the following reusable utility class in our project:

    public static class TryWithAwaitInCatch
    {
        public static async Task ExecuteAndHandleErrorAsync(Func actionAsync,
            Func> errorHandlerAsync)
        {
            ExceptionDispatchInfo capturedException = null;
            try
            {
                await actionAsync().ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                capturedException = ExceptionDispatchInfo.Capture(ex);
            }
    
            if (capturedException != null)
            {
                bool needsThrow = await errorHandlerAsync(capturedException.SourceException).ConfigureAwait(false);
                if (needsThrow)
                {
                    capturedException.Throw();
                }
            }
        }
    }
    

    One would use it as follows:

        public async Task OnDoSomething()
        {
            await TryWithAwaitInCatch.ExecuteAndHandleErrorAsync(
                async () => await DoSomethingAsync(),
                async (ex) => { await ShowMessageAsync("Error: " + ex.Message); return false; }
            );
        }
    

    Feel free to improve the naming, we kept it intentionally verbose. Note that there is no need to capture the context inside the wrapper as it is already captured in the call site, hence ConfigureAwait(false).

提交回复
热议问题