我希望了解在多播委托中处理异常的最佳方法是什么?
我的问题是,如果一个方法在多播委托执行中抛出异常,会发生什么?会停止吗?还是继续执行?如何处理?如果有人能分享一个带有说明的小程序,那将非常有帮助....谢谢....
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);
}
}
}
它将像任何其他异常一样工作,并且与非多播委托相同:异常向上传播到堆栈。
GetInvocationList
返回的数组中的每个元素都与原始委托具有相同的类型,但只包含单个操作。对此感到困惑是可以理解的 - 缺乏良好术语并没有帮助 :( - Jon SkeetAction
、EventHandler
等。在某些方面,你可能不想一开始就过多地考虑我的代码——它比我想象中的要糟糕,部分原因是因为C#不允许我添加约束来强制T
成为委托类型。 - Jon Skeet