在下面的代码中,我有两个类,一个在单独的线程中运行并触发事件,另一个订阅此事件并从事件接收数据。我基于 Jon Skeet 的文章http://csharpindepth.com/Articles/Chapter2/Events.aspx的事件代码
在这篇文章http://www.codeproject.com/Articles/37474/Threadsafe-Events它说......
出于这个原因,我推荐 Jon Skeet 在 Delegates and Events 最后推荐的相同方法:“不要那样做”,即不要以多线程方式使用事件。如果对象上存在事件,那么只有一个线程应该能够订阅或取消订阅该事件,并且将引发该事件的同一线程。
现在显然我的设计打破了这一点,因为它在与它订阅的线程不同的线程上触发事件。我如何修改我的设计,使其遵守不以多线程方式使用事件的原则,或者这是不可能的?
我想到的另一种方法是将我的回调方法作为委托传递给B类并调用它而不是调用事件?
我可能有完全错误的一端,所以任何澄清将不胜感激。
注意:我知道 .Net 4.0 显然已经解决了这个问题,但是我仍然对在 .Net 4 之前是否有办法做到这一点感兴趣
public delegate void MyDelegate(int a);
class A
{
void main()
{
B bObject = new B();
bObject.MyEvent += new MyDelegate(NiceMethod);
bObject.Run();
}
void NiceMethod(int a)
{
Console.Writeline({0}, a);
}
}
class B
{
readonly object eventLock = new object();
MyDelegate myDel;
public event MyDelegate MyEvent
{
add
{
lock (eventLock)
{
myDel += value;
}
}
remove
{
lock (eventLock)
{
myDel -= value;
}
}
}
//Assume this runs in a new thread and calls back data using MyEvent
//Have ommited thread code for simplicity
public void Run()
{
for (int i = 0; i < 100; i++)
{
Thread.Sleep(1000);
MyDelegate handler;
lock (someEventLock)
{
handler = myDel;
}
if (handler != null)
{
handler (i);
}
}
}
}