当多播委托中的方法发生异常时会发生什么?

7

我希望了解在多播委托中处理异常的最佳方法是什么?

我的问题是,如果一个方法在多播委托执行中抛出异常,会发生什么?会停止吗?还是继续执行?如何处理?如果有人能分享一个带有说明的小程序,那将非常有帮助....谢谢....

2个回答

17
异常将立即传播,委托调用列表中后续的任何“后续”操作都将不会执行。如果您想确保执行所有委托——例如聚合所有异常——则需要调用Delegate.GetInvocationList,将这些委托强制转换为与原始委托相同的类型,并一个接一个地调用它们,捕获抛出的异常。
下面是一些示例代码,它可以做到这一点——理想情况下,最好以更通用的方式构建一个新委托,该委托(在执行时)将执行所有组成委托并聚合异常...但这是一个开始。
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

class Program
{
    public static void Main()
    {
        Action x = null;
        x += () => Console.WriteLine("First");
        x += () => { throw new Exception("Bang 1"); };
        x += () => { throw new Exception("Bang 2"); };
        x += () => Console.WriteLine("Second");

        try
        {
            ExecuteAll<Action>(x, action => action());
        }
        catch (AggregateException e)
        {
            Console.WriteLine(e);
        }
    }

    public static void ExecuteAll<T>(Delegate multi, Action<T> invoker)
    {
        List<Exception> exceptions = new List<Exception>();
        foreach (var single in multi.GetInvocationList())
        {
            try
            {
                invoker((T)(object)single);
            }
            catch (Exception e)
            {
                exceptions.Add(e);
            }
        }
        if (exceptions.Count > 0)
        {
            throw new AggregateException(exceptions);
        }
    }
}

嗨Jon,谢谢,这正是我想要理解的。好的,你陈述中有一件事我没明白,“将每个委托强制转换为相同类型”是指多个单独的委托吗?呃,抱歉,由于我是新手,所以无法理解...我知道这可能很傻.... - Jasmine
@Divine:GetInvocationList 返回的数组中的每个元素都与原始委托具有相同的类型,但只包含单个操作。对此感到困惑是可以理解的 - 缺乏良好术语并没有帮助 :( - Jon Skeet
这里我有点困惑术语“类型”...你所说的类型是指返回类型还是签名?就我所知,void是多播委托的返回类型...这对我来说是一个很棒的程序,我会在我的VS中使用它并理解它...:)非常感谢Jon,我很感激... :) - Jasmine
@Divine:委托的类型取决于你调用它的对象,例如ActionEventHandler等。在某些方面,你可能不想一开始就过多地考虑我的代码——它比我想象中的要糟糕,部分原因是因为C#不允许我添加约束来强制T成为委托类型。 - Jon Skeet
嗯,太好了,非常感谢Jon :) 我明白了,会更深入地研究这些东西...你的代码对我来说很有帮助,可以让我开始学习...正如你建议的那样,我会更深入地理解它以进入泛型...但是泛型对我来说还是很新的:P :) 非常感谢您帮助我理解这个问题,以及您的时间和友善的回复:) 干杯 - Jasmine

0

它将像任何其他异常一样工作,并且与非多播委托相同:异常向上传播到堆栈。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接