在try / catch语句进行的await一个好的解决方案/最后? [英] A good solution for await in try/catch/finally?

查看:3170
本文介绍了在try / catch语句进行的await一个好的解决方案/最后?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要重新抛出异常(与它的堆栈跟踪之前调用一个异步方法在块)是这样的:

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

try
{
    // Do something
}
catch
{
    // <- Clean things here with async methods
    throw;
}

但不幸的是你不能使用等待最后块。我了解到这是因为编译器没有任何办法回去了块来执行你是什么的await 指令或类似的东西...

But unfortunately you can't use await in a catch or finally block. I learned it's because the compiler doesn't have any way to go back in a catch block to execute what is after your await instruction or something like that...

我试图用 Task.Wait()来代替等待,我得到了一个僵局。我搜索在网络上我怎么能避免这种情况,发现<一个href=\"http://www.tugberkugurlu.com/archive/the-perfect-recipe-to-shoot-yourself-in-the-foot-ending-up-with-a-deadlock-using-the-c-sharp-5-0-asynchronous-language-features\">this网站。

I tried to use Task.Wait() to replace await and I got a deadlock. I searched on the Web how I could avoid this and found this site.

既然不能改变异步方法,我也不知道,如果他们使用 ConfigureAwait(假),我创建了这些方法,它采取了 Func键&LT;任务&GT; 启动异步方法,一旦我们在不同的线程(以避免死锁),并为其完成等待:

Since I can't change the async methods nor do I know if they use ConfigureAwait(false), I created these methods which take a Func<Task> that starts an async method once we are on a different thread (to avoid a deadlock) and waits for its completion:

public static void AwaitTaskSync(Func<Task> action)
{
    Task.Run(async () => await action().ConfigureAwait(false)).Wait();
}

public static TResult AwaitTaskSync<TResult>(Func<Task<TResult>> action)
{
    return Task.Run(async () => await action().ConfigureAwait(false)).Result;
}

public static void AwaitSync(Func<IAsyncAction> action)
{
    AwaitTaskSync(() => action().AsTask());
}

public static TResult AwaitSync<TResult>(Func<IAsyncOperation<TResult>> action)
{
    return AwaitTaskSync(() => action().AsTask());
}

所以我的问题是:你认为这个code是好

So my questions is: Do you think this code is okay?

当然,如果你有一些改进或知道一个更好的方法,我在听! :)

Of course, if you have some enhancements or know a better approach, I'm listening! :)

推荐答案

您可以将逻辑块外后重新抛出异常,如果需要的话,由使用<一个href=\"http://msdn.microsoft.com/en-us/library/system.runtime.exceptionservices.exceptiondispatchinfo.aspx\"><$c$c>ExceptionDispatchInfo.

You can move the logic outside of the catch block and rethrow the exception after, if needed, by using ExceptionDispatchInfo.

static async Task f()
{
    ExceptionDispatchInfo capturedException = null;
    try
    {
        await TaskThatFails();
    }
    catch (MyException ex)
    {
        capturedException = ExceptionDispatchInfo.Capture(ex);
    }

    if (capturedException != null)
    {
        await ExceptionHandler();

        capturedException.Throw();
    }
}

这样,当主叫检查异常的堆栈跟踪属性,在 TaskThatFails 它仍然记录在那里被扔

This way, when the caller inspects the exception's StackTrace property, it still records where inside TaskThatFails it was thrown.

这篇关于在try / catch语句进行的await一个好的解决方案/最后?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆