如何在 for 循环中同时运行异步函数并捕获 C# 中的所有错误

问题描述 投票:0回答:2

我正在尝试对多个项目执行异步函数。此外,我想捕获此函数中可能抛出的所有错误。

运行以下代码时,我仍然收到“未处理的异常”错误,而不是 WriteLine 语句为每个项目打印实际的错误消息“某些错误”。

public async Task RunEachItem()
{
    var tasks = new List<Task>();

    foreach (var item in Items)
    {
        tasks.Add(SomeAsyncFunc(item.Index));
    }

    try
    {
        await Task.WhenAll(tasks);
    }
    catch(Exception e)
    {
        Console.WriteLine(e.Message);
    }
}

public async Task SomeAsyncFunc(int index)
{
    // somehow process item using index parameter

    throw new Exception("some error");
}

我将非常感谢任何帮助,因为我不知道如何使用谷歌或人工智能工具来完成此任务。

c# asynchronous error-handling
2个回答
0
投票

您必须使用包含所有任务的可等待任务的属性

Exception.InnerExceptions

class Foo
{
    public async Task RunEachItem()
    {
        var tasks = new List<Task>();

        for (int i = 0; i < 10; i++)
        {
            tasks.Add(SomeAsyncFunc(i));
        }

        Task t = null!;
        try
        {
           t = Task.WhenAll(tasks);
           await t;
        }
        catch(Exception e)
        {
            var all = t.Exception.InnerExceptions;
            foreach (Exception exception in all)
            {
                Console.WriteLine(exception.Message);
            }
        }
    }

    public async Task SomeAsyncFunc(int index)
    {
        // somehow process item using index parameter

        throw new Exception($"some error {index}");
    }
}

这段代码的输出是

some error 0
some error 1
some error 2
...

0
投票

在进一步搜索谷歌之后,我发现了关于这个主题的这篇this文章。 似乎

await Task.WhenAll(tasks)
周围的 try-catch 语句只捕获第一个异常。因此,您需要使用“缓冲区调用”来包围异步函数,如下所示:


private async Task BufferCall(int index)
{
    try
    {
       await someAsyncFunc(index);
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
    }
}

// ...

tasks.Add(BufferCall(item.Index));

现在唯一的问题是,函数是否仍然以这种方式同时运行......

© www.soinside.com 2019 - 2024. All rights reserved.