我需要在catch块中调用async方法,然后再次抛出异常(及其堆栈跟踪),如下所示:

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

但不幸的是,你不能在catchfinally街区使用await.我了解到这是因为编译器无法返回catch块来执行await指令之后的内容或类似的内容...

我试着用Task.Wait()来代替await,结果我陷入了僵局.我在网上搜索了如何避免这种情况,找到了this site个.

由于我无法更改async个方法,也不知道它们是否使用ConfigureAwait(false),所以我创建了这些方法,它们采用Func<Task>,一旦我们在不同的线程上(以避免死锁),就会启动一个异步方法,并等待其完成:

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());
}

所以我的问题是:你认为这个代码行吗?

当然,如果您有一些增强功能或知道更好的方法,我会倾听您的意见!:)

推荐答案

您可以将逻辑移到catch块之外,并在需要时使用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();
    }
}

这样,当调用方判断异常的StackTrace属性时,它仍然会记录抛出异常的位置.

.net相关问答推荐

API响应返回null错误. NET MAUI

我的Azure应用服务从哪里获取应用设置?

Blazor服务器应用程序需要在页面上点击才能与元素交互

是否必须使用 Visual Studio 预览才能使用 MAUI?

C#/.NET + VisualStudio,命名空间问题

.gitignore 和 Visual Studio 项目:忽略 bin/Debug 目录但不忽略 bin/Release 目录

在 C# 中获取 log4net 日志(log)文件

将屏幕捕获为位图

(C# 7.2)私有保护修饰符的用例是什么?

我什么时候应该在 C# 中使用使用块?

编译错误:显式实现接口时修饰符 'public' 对此项目无效

序列化私有成员数据

.net:System.Web.Mail 与 System.Net.Mail

在 C# 中转义命令行参数

.NET 反射的成本是多少?

从 .NET 中的字符串末尾修剪字符串 - 为什么会丢失?

加载程序集、查找类和调用 Run() 方法的正确方法

如何在 WPF 中的 Xaml 文件中添加注释?

合并两个(或更多)PDF

.NET 委托类型的正确命名约定?