c# - 在异步委托(delegate)中捕获异常

标签 c# async-await

我有这个代码:

    public async Task AsyncMethod()
    {
        await Task.Factory.StartNew(() =>
        {
            throw new Exception();
        });
    }

    public ActionResult Index()
    {
        var t1 = Task.Factory.StartNew(() => { throw new Exception(); });
        var t2 = Task.Factory.StartNew(() => { throw new Exception();});
        var t3 = Task.Factory.StartNew(async () => { await AsyncMethod(); });

        try 
        {
            Task.WaitAll(t1, t2, t3);
        }
        catch (AggregateException ex)
        {
            var count1 = ex.InnerExceptions.Count;
            var count2 = ex.Flatten().InnerExceptions.Count;

            throw;
        }

        return View();
    }

我想了解为什么 count1 和 count2 变量是 2 而不是 3,以及如何在 AsyncMethod 中获取第三个异常?

最佳答案

I would like to understand why the count1 and count2 variables are 2 and not 3 and how can I get the third exception inside AsyncMethod?

Task.Factory.StartNew 返回一个基本的 Task。如果你给它传递一个 async 委托(delegate),那么返回的 Task 只代表 async 方法的开始(直到它屈服于它的点来电者)。

您应该将 Task.Runasync 代码一起使用。 Task.Run 将为 async 委托(delegate)创建一个 Task 包装器,因此从 Task 返回的 Task .Run 表示整个async 方法。

Stephen Toub 有 an excellent blog post detailing the differences between Task.Run and Task.Factory.StartNew .

此外,正如 usr 所提到的,每当您在 GUI 或 ASP.NET 上下文中阻塞 Task 而不是 await 时,就会遇到死锁问题。我有 a blog post that goes into detail about this deadlock problem .您应该使用 await Task.WhenAll 而不是 Task.WaitAll

因此,这是应用了两项更改的代码:

public async Task AsyncMethod()
{
    await Task.Run(() =>
    {
        throw new Exception();
    });
}

public async Task<ActionResult> Index()
{
    var t1 = Task.Run(() => { throw new Exception(); });
    var t2 = Task.Run(() => { throw new Exception();});
    var t3 = Task.Run(async () => { await AsyncMethod(); });

    try 
    {
        await Task.WhenAll(t1, t2, t3);
    }
    catch (Exception)
    {
        var ex1 = t1.Exception.InnerException;
        var ex2 = t2.Exception.InnerException;
        var ex3 = t3.Exception.InnerException;

        throw;
    }

    return View();
}

关于c# - 在异步委托(delegate)中捕获异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14102135/

相关文章:

c# - 如何将 Char[] 或 String 转换为 Char* 以在 C# 中初始化 SecureString?

node.js - 如何使用 NodeJs MySql2 库 async/await 捕获连接错误

c# - System.Threading.Tasks 中的 NullReferenceException 调用 HttpClient.GetAsync(url)

azure - 在服务总线客户端中处理取消

c# - TableLayoutPanel 显示垂直滚动

c# - 从旋转值的方向移动 Sprite ?

c# - .Net 应用程序性能优化器

javascript - for of 循环,等到值被定义

c# - 为什么这个 async/await 代码会生成 "...not all code paths return a value"?

c# - “Application.Restart”在 ClickOnce 部署的应用程序中不起作用