AggregateException C#示例

Dan*_*Dan 26 c# aggregate exception

我在网上看到了一个AggregateException的例子,我正在试图弄清楚它是如何工作的,所以我编写了一个简单的例子,但由于某种原因我的代码不起作用

有人可以解释一下我的问题是什么

public static void Main()
{
    try
    {
        Parallel.For(0, 500000, i =>
        {
            if (i == 10523)
                throw new TimeoutException("i = 10523");
            Console.WriteLine(i + "\n");
        });
    }
    catch (AggregateException exception)
    {
        foreach (Exception ex in exception.InnerExceptions)
        {
            Console.WriteLine(ex.ToString());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 20

你需要在内部异常上调用"Handled".从MSDN关于"句柄"的文档:

每次调用谓词都会返回true或false,以指示是否处理了Exception.在所有调用之后,如果未处理任何异常,则所有未处理的异常将被放入将抛出的新AggregateException中.否则,Handle方法只返回.如果谓词的任何调用抛出异常,它将停止处理任何更多异常并立即按原样传播抛出的异常.

示例代码,也来自MSDN:

public static void Main()
{
    var task1 = Task.Run(() => { throw new CustomException("This exception is expected!"); });

    try 
    {
        task1.Wait();
    }
    catch (AggregateException ae)
    {
        // Call the Handle method to handle the custom exception,
        // otherwise rethrow the exception.
        ae.Handle(ex => 
        { 
            if (ex is CustomException)
                Console.WriteLine(ex.Message);
            return ex is CustomException;
        });
    }
}
Run Code Online (Sandbox Code Playgroud)


Yah*_*hia 11

使用Parallel时,"job"(此处从0到500000计数)被分成几个工作线程.其中每一个都可能抛出异常.在示例中,异常被编码为在10523上运行的线程中发生.在现实世界中,可能发生多个异常(在不同的线程中) - AggregateException只是在Parallel运行时发生的所有异常的"容器"你不会失去任何例外......

  • 你说得对,但我认为你所描述的行为只是在VS中运行并进行调试时才会发生. (2认同)

Kęd*_*rzu 10

AggregateException通常用于捕获异常,这可能在等待Task完成时发生.因为Task一般可以由多个其他人组成,我们不知道,是否会抛出一个或多个异常.

请检查以下示例:

// set up your task
Action<int> job = (int i) =>
{
    if (i % 100 == 0)
        throw new TimeoutException("i = " + i);
};

// we want many tasks to run in paralell
var tasks = new Task[1000];
for (var i = 0; i < 1000; i++)
{
    // assign to other variable,
    // or it will use the same number for every task
    var j = i; 
    // run your task
    var task = Task.Run(() => job(j));
    // save it
    tasks[i] = task;
}

try
{
    // wait for all the tasks to finish in a blocking manner
    Task.WaitAll(tasks);

}
catch (AggregateException e)
{
    // catch whatever was thrown
    foreach (Exception ex in e.InnerExceptions)
        Console.WriteLine(ex.Message);
}
Run Code Online (Sandbox Code Playgroud)