ThreadPool错过了事件

时间:2017-11-06 11:08:16

标签: c# multithreading threadpool blockingcollection

我需要对事件进行排队并并行执行它们。

我的C#代码将阻塞集合中的事件排队,并使用ThreadPool在工作线程上执行每个事件。但是,如果事件以2000事件/秒或更高的速率排队,则会遗漏某些事件。当我搜索这个问题时,我发现ThreadPool可以拒绝某些请求,或者如果没有可用的线程则保留它们,来自this link

  

更糟糕的是,依赖于线程池中的线程的传入请求可能处于暂停状态,或者甚至可能被拒绝主要是因为线程池可能没有可用的线程来处理来电请求

注意:此问题仅在使用带有Core i5的笔记本电脑时出现,当我使用Core i7尝试使用时,它运行正常。

以下是代码片段:

public static void ExecuteEvents()
{
    foreach (EventData data in blockingCollection.GetConsumingEnumerable())
    {
        switch (data.EventType)
        {
            case EventType1:
                ThreadPool.QueueUserWorkItem(o =>
                {
                    Function1(data);
                });
                break;
            case EventType2:
                ThreadPool.QueueUserWorkItem(o =>
                {
                    Function2(data);
                });
            default:
                break;
        }
    }
}

1 个答案:

答案 0 :(得分:3)

看起来你没有遇到线程池问题。看起来你有关闭的问题。

您应首先在循环中创建局部变量。问题是当线程池执行操作时,它会引用不断更改的EventData data变量。因此,您应该首先创建一个局部变量。(它将打包在一个显示类中,因为局部变量是从一个放在范围列表中的方法引用的。)

public static void ExecuteEvents()
{
    foreach (EventData data in blockingCollection.GetConsumingEnumerable())
    {
        var local = data;
        switch (local.EventType)
        {
            case EventType1:
                ThreadPool.QueueUserWorkItem(o =>
                {
                    Function1(local);
                });
                break;
            case EventType2:
                ThreadPool.QueueUserWorkItem(o =>
                {
                    Function2(local);
                });
            default:
                break;
        }
    }
}

有关闭包的更多信息,请查看here