这个问题分为两个部分:
事件是否会阻止线程,还是会异步启动EventHandler的执行,同时线程继续运行?
individual EventHandlers(订阅了事件)是一个接一个地同步运行,还是在不能保证其他人不会同时运行的情况下异步运行?
这个问题分为两个部分:
事件是否会阻止线程,还是会异步启动EventHandler的执行,同时线程继续运行?
individual EventHandlers(订阅了事件)是一个接一个地同步运行,还是在不能保证其他人不会同时运行的情况下异步运行?
是的,它们是同步的.
要回答您的问题:
我也对event
的内部机制和相关操作感到好奇.所以我编写了一个简单的程序,并使用ildasm
来研究它的实现.
简单的答案是
Delegate.Combine()
美元完成的Delegate.Remove()
美元完成的我就是这么做的.我使用的程序:
public class Foo
{
// cool, it can return a value! which value it returns if there're multiple
// subscribers? answer (by trying): the last subscriber.
public event Func<int, string> OnCall;
private int val = 1;
public void Do()
{
if (OnCall != null)
{
var res = OnCall(val++);
Console.WriteLine($"publisher got back a {res}");
}
}
}
public class Program
{
static void Main(string[] args)
{
var foo = new Foo();
foo.OnCall += i =>
{
Console.WriteLine($"sub2: I've got a {i}");
return "sub2";
};
foo.OnCall += i =>
{
Console.WriteLine($"sub1: I've got a {i}");
return "sub1";
};
foo.Do();
foo.Do();
}
}
以下是Foo的实现:
请注意,有一个field OnCall
和一个event OnCall
.字段OnCall
显然是支持属性.这只是一个Func<int, string>
,没什么特别的.
现在有趣的部分是:
add_OnCall(Func<int, string>)
个remove_OnCall(Func<int, string>)
Do()
中如何调用OnCall
下面是CIL中的缩写add_OnCall
实现.有趣的是,它使用Delegate.Combine
来连接两个代理.
.method public hidebysig specialname instance void
add_OnCall(class [mscorlib]System.Func`2<int32,string> 'value') cil managed
{
// ...
.locals init (class [mscorlib]System.Func`2<int32,string> V_0,
class [mscorlib]System.Func`2<int32,string> V_1,
class [mscorlib]System.Func`2<int32,string> V_2)
IL_0000: ldarg.0
IL_0001: ldfld class [mscorlib]System.Func`2<int32,string> ConsoleApp1.Foo::OnCall
// ...
IL_000b: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate,
class [mscorlib]System.Delegate)
// ...
} // end of method Foo::add_OnCall
同样,remove_OnCall
中使用Delegate.Remove
.
要在Do()
中调用OnCall
,它只需在加载arg后调用最终连接的委托:
IL_0026: callvirt instance !1 class [mscorlib]System.Func`2<int32,string>::Invoke(!0)
最后,在Main
中,不出所料,订阅OnCall
事件是通过调用Foo
实例上的add_OnCall
方法来完成的.