在.NET中,事件处理的线程是什么?
我试图在c#中实现一个生产者/消费者模式。 我有一个消费者线程监视共享队列,和一个生产者线程放置到共享队列的项目。 生产者线程订阅接收数据…也就是说,它有一个事件处理程序,只是坐在旁边,并等待一个OnData事件触发(数据从第三方api发送)。 当它获得数据时,它将它放在队列中,以便消费者可以处理它。
当OnData事件在生产者中触发时,我曾预料它将由我的生产者线程来处理。 但是,这似乎并没有发生。 OnData事件看起来好像它正在一个新的线程上处理! 这是如何.NET总是工作…事件是在自己的线程处理? 我可以控制什么线程处理事件,当他们被提出? 如果几乎同时发生数百个事件会怎样呢?每个事件都有自己的线程?
重读这个问题后,我想现在我明白了这个问题。 你基本上有这样的东西:
class Producer { public Producer(ExternalSource src) { src.OnData += externalSource_OnData; } private void externalSource_OnData(object sender, ExternalSourceDataEventArgs e) { // put e.Data onto the queue } }
然后你有一个消费者线程,从那个队列中抽取东西。 问题是OnData事件是由你的ExternalSource
对象触发的 – 在任何正在运行的线程上。
C# event
基本上只是一个易于使用的委托集合,“触发”一个事件只会导致运行时循环遍历所有的委托并逐一触发它们。
所以你的OnData事件处理程序在ExternalSource
运行的任何线程上被调用。
除非你自己编组,否则一个事件将在任何线程调用它时执行; 事件调用的方式没有什么特别之处,而你的生产者线程没有事件处理程序,你的生产者线程只是简单地说:“嘿,当你触发这个事件时,调用这个函数”。 没有任何东西会导致事件执行发生在附加线程上,也不会在它自己的线程上发生(除非您使用BeginInvoke
而不是正常调用事件的委托,但是这只会在ThreadPool
上执行它)。
使用Invoke
提升事件与Invoke
方法相同 – 它会在您提出的同一个线程中执行。
用BeginInvoke
引发事件使用ThreadPool
。 这里有一些小的细节
你必须使用autoresetevent处理这个问题…..在autoresetevent当生产者生产它设置信号,然后消费者重置其信号和消费..消费后消费设置信号,然后只有生产者生产…
AutoResetEvent pro = new AutoResetEvent(false); AutoResetEvent con = new AutoResetEvent(true); public void produser() { while(true) { con.WaitOne(); pro.Set(); } } public void consumer() { while (true) { pro.WaitOne(); .................**** con.Set(); } } private void button1_Click(object sender, EventArgs e) { Thread th1 = new Thread(produser); th1.Start(); Thread th2 = new Thread(consumer); th2.Start(); }