C# 线程池未命中事件
我需要将事件排队并并行执行它们 我的C#代码在阻塞集合中对事件进行排队,并使用线程池在工作线程上执行每个事件。但是,如果事件以2000事件/秒或更高的速率排队,则会错过某些事件。当我搜索这个问题时,我发现线程池可以拒绝一些请求,或者在没有可用线程的情况下保留它们,从: 更糟糕的是,依赖于线程池中线程的传入请求可能会被搁置,甚至可能会被拒绝,这主要是因为线程池中可能没有可用线程来处理传入请求 注意:这个问题只有在使用Core i5的笔记本电脑时才会出现,当我尝试使用Core i7时,它工作正常 下面是一段代码:C# 线程池未命中事件,c#,multithreading,threadpool,blockingcollection,C#,Multithreading,Threadpool,Blockingcollection,我需要将事件排队并并行执行它们 我的C#代码在阻塞集合中对事件进行排队,并使用线程池在工作线程上执行每个事件。但是,如果事件以2000事件/秒或更高的速率排队,则会错过某些事件。当我搜索这个问题时,我发现线程池可以拒绝一些请求,或者在没有可用线程的情况下保留它们,从: 更糟糕的是,依赖于线程池中线程的传入请求可能会被搁置,甚至可能会被拒绝,这主要是因为线程池中可能没有可用线程来处理传入请求 注意:这个问题只有在使用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;
}
}
}
看起来您的线程池没有问题。看起来您的闭包有问题 您应该首先在循环中创建一个局部变量。问题在于,当线程池执行该操作时,它引用的是不断变化的
EventData
变量。因此,您应该首先创建一个局部变量(它将被打包在一个displayclass中,因为局部变量是从一个放在范围外列表中的方法引用的)
有关闭包的更多信息,请查看
线程池从未听说过被拒绝的工作项。听起来是另外一回事。你认为其他原因是什么@Jeroenvanlangen您是否尝试添加一些日志,以防确定您神秘消失的日志不是eventtyp1或EventTyp2?您是否考虑过使用Microsoft的反应式框架来执行此操作?我非常确定它们是event type 1或event type 2,因为我将它们添加到blocking集合中,并使用了正确的类型@BugFinder如果OP是在C#3.0或更早版本上,这将是正确的。如果他们使用的是C#4.0+,这不会改变任何事情,根据他们的评论,情况似乎就是这样。
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;
}
}
}