C# 在.NET中,将在哪个线程中处理事件?

C# 在.NET中,将在哪个线程中处理事件?,c#,.net,events,multithreading,delegates,C#,.net,Events,Multithreading,Delegates,我尝试在c#中实现生产者/消费者模式。我有一个监视共享队列的使用者线程和一个将项目放入共享队列的生产者线程。生产者线程被订阅接收数据…也就是说,它有一个事件处理程序,只是坐在那里等待OnData事件触发(数据是从第三方api发送的)。当它获取数据时,它会将数据粘贴到队列中,以便消费者能够处理它 当OnData事件在producer中触发时,我希望它由我的producer线程处理。但这似乎不是正在发生的事情。OnData事件似乎是在一个新线程上处理的!net总是这样工作的……事件是在它们自己的线程

我尝试在c#中实现生产者/消费者模式。我有一个监视共享队列的使用者线程和一个将项目放入共享队列的生产者线程。生产者线程被订阅接收数据…也就是说,它有一个事件处理程序,只是坐在那里等待OnData事件触发(数据是从第三方api发送的)。当它获取数据时,它会将数据粘贴到队列中,以便消费者能够处理它


当OnData事件在producer中触发时,我希望它由我的producer线程处理。但这似乎不是正在发生的事情。OnData事件似乎是在一个新线程上处理的!net总是这样工作的……事件是在它们自己的线程上处理的吗?我可以控制引发事件时哪个线程将处理事件吗?如果几乎同时引发数百个事件……每个事件都会有自己的线程吗?

除非您自己进行封送处理,否则事件将在调用它的任何线程上执行;调用事件的方式没有什么特别之处,并且您的生产者线程没有事件处理程序,您的生产者线程只是简单地说“嘿,当您触发此事件时,请调用此函数”。其中没有任何内容会导致事件在附加线程上执行,也不会在其自身线程上执行(除非您使用
BeginInvoke
而不是正常调用事件的委托,但这只会在
ThreadPool
上执行)。重新阅读问题后,我想我现在明白这个问题了。你基本上得到了这样的东西:

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#
事件
s基本上只是一个易于使用的委托集合,“触发”事件只会导致运行时循环遍历所有委托,并一次触发一个委托


因此,在运行
ExternalSource
的任何线程上都会调用OnData事件处理程序。

使用
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();
}

发布一些代码和/或您正在使用的类可能会有所帮助。您是在谈论C#
事件
关键字意义上的事件,还是在
事件WaitHandle
意义上的事件?我想你应该发布一些代码…@codeka:听上去像是
事件
,考虑到他的帖子。谢谢codeka,你已经完全掌握了。我将检查externalSource事件正在发生的线程。感谢您的帮助。使用Invoke和BeginInvoke触发事件时情况会有所不同。.BeginInvoke在线程池的不同线程中调用事件订阅服务器(在后台线程中)@SatyajitMohanty您也提到了Invoke。调用是否在新线程上执行?