繁体   English   中英

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

[英]In .NET, what thread will Events be handled in?

我试图在 C# 中实现生产者/消费者模式。 我有一个监视共享队列的消费者线程和一个将项目放置到共享队列的生产者线程。 生产者线程被订阅以接收数据……也就是说,它有一个事件处理程序,只是坐在那里等待 OnData 事件触发(数据是从 3rd 方 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 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();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM