public delegate void EventHandler( object sender, EventArgs e )
默认情况下,EventHandler将发送对象和一些事件参数作为参数。
public class MyEventArgs : EventArgs
{
public int Value { get; set; }
public MyEventArgs(int value)
{
Value = value;
}
}
public class Pub
{
public event EventHandler<MyEventArgs> OnChange = delegate { };
public void Raise()
{
OnChange(this, new MyEventArgs(1));
}
}
class Program
{
static void Main(string[] args)
{
Pub p = new Pub();
p.OnChange += (sender, e) => Console.WriteLine("Sub 1.Value:" + e.Value);
p.OnChange += (sender, e) => Console.WriteLine("Sub 2.Value:" + e.Value);
p.Raise();
Console.WriteLine("Press enter !");
Console.ReadLine();
}
}
如上代码中通过pub类使用通用的EventHandler,它触发EventHandler OnChange时需要传递的事件参数类型,在上面代码片段中为MyArgs
事件中的异常
我们继续说一种情况.大家看如下代码片段
public class MyEventArgs : EventArgs
{
public int Value { get; set; }
public MyEventArgs(int value)
{
Value = value;
}
}
public class Pub
{
public event EventHandler<MyEventArgs> OnChange = delegate { };
public void Raise()
{
OnChange(this, new MyEventArgs(1));
}
}
class Program
{
static void Main(string[] args)
{
Pub p = new Pub();
p.OnChange += (sender, e) => Console.WriteLine("Sub 1.Value:" + e.Value);
p.OnChange += (sender, e) => { throw new Exception(); };
p.OnChange += (sender, e) => Console.WriteLine("Sub 2.Value:" + e.Value);
p.Raise();
Console.WriteLine("Press enter !");
Console.ReadLine();
}
}
运行如上代码后,大家会发现第一个订阅者已经执行成功了,第二个订阅者引发了异常,而第三个订阅者未被调用.这是一个很尴尬的事情.
如果说我们觉得如上的过程不是我们预期的,我们需要手动引发事件并处理异常,这时候我们可以使用Delegate基类中定义的GetInvoctionList来帮助我们实现这些。
我们继续看如下代码
public class MyEventArgs : EventArgs
{
public int Value { get; set; }
public MyEventArgs(int value)
{
Value = value;
}
}
public class Pub
{
public event EventHandler<MyEventArgs> OnChange = delegate { };
public void Raise()
{
MyEventArgs eventArgs = new MyEventArgs(1);
List<Exception> exceptions = new List<Exception>();
foreach (Delegate handler in OnChange.GetInvocationList())
{
try
{
handler.DynamicInvoke(this, eventArgs);
}
catch (Exception e)
{
exceptions.Add(e);
}
}
if (exceptions.Any())
{
throw new AggregateException(exceptions);
}
}
}
class Program
{
static void Main(string[] args)
{
Pub p = new Pub();
p.OnChange += (sender, e) => Console.WriteLine("Sub 1.Value:" + e.Value);
p.OnChange += (sender, e) => { throw new Exception(); };
p.OnChange += (sender, e) => Console.WriteLine("Sub 2.Value:" + e.Value);
p.Raise();
Console.WriteLine("Press enter !");
Console.ReadLine();
}
}










