在.NET中,处理事件的线程是什么?

时间:2010-03-17 02:53:15

标签: c# .net events multithreading delegates

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

当OnData事件在生产者中触发时,我原本期望它由我的生产者线程处理。但这似乎并不是正在发生的事情。 OnData事件看起来好像是在新线程上处理的!这是.net始终如何工作...事件是在自己的线程上处理的?我可以控制什么线程在它们被引发时处理事件?如果几乎同时引发了数百个事件......每个事件都有自己的线程吗?

4 个答案:

答案 0 :(得分:87)

重新阅读问题之后,我想我现在明白了这个问题。你基本上得到了这样的东西:

class Producer
{
    public Producer(ExternalSource src)
    {
        src.OnData += externalSource_OnData;
    }

    private void externalSource_OnData(object sender, ExternalSourceDataEventArgs e)
    {
        // put e.Data onto the queue
    }
}

然后你有一个消费者线程从那个队列中拉出东西。问题是你的ExternalSource对象触发了OnData事件 - 它正在运行的任何线程上。

C#event s基本上只是一个易于使用的委托集合,“触发”事件只会导致运行时循环遍历所有委托并一次触发一个委托。

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

答案 1 :(得分:23)

除非你自己编组,否则一个事件将在任何调用它的线程上执行;调用事件的方式并没有什么特别之处,并且你的生产者线程没有事件处理程序,你的生产者线程简单地说“嘿,当你触发这个事件时,调用这个函数”。在那里没有任何东西导致事件执行发生在附加线程上,也没有发生在它自己的线程上(除非你使用BeginInvoke而不是正常调用事件的委托,但这只会在{{{ 1}})。

答案 2 :(得分:9)

使用Invoke引发事件与调用方法相同 - 它会在您引发它的同一个线程中执行。

使用BeginInvoke举办活动会使用ThreadPool。以下是一些minor details

答案 3 :(得分:-4)

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