【发布时间】:2013-08-24 01:20:37
【问题描述】:
我的分析器在调用 QueueUserWorkItem() 时出现间歇性峰值。我每秒排队大约 20 个工作。就复杂性而言,每项工作大致相同。 95% 的作业在调用 QueueUserWorkItem 时花费的时间不到 0.01 毫秒。但是每隔几秒钟,似乎是随机的,一项工作需要 20 到 60 毫秒!
我正在尝试构建一个流畅的模拟,只是将我的后台任务排队会导致我的帧率出现严重故障。
这不是作业实际完成所需的时间,而是简单地排队作业所花费的时间。我希望这几乎不需要任何时间,所以这非常令人沮丧。
foreach ( Job j in jobs_to_process )
{
Job current_job = j;
if ( !current_job.queued )
{
current_job.queued = true;
Profiler.BeginSample("QueueWorkItem");
ThreadPool.UnsafeQueueUserWorkItem( current_job.DoCalculation, null );
Profiler.EndSample();
}
}
//now I remove queued items from jobs_to_process, move them to jobs_in_progress list
我尝试过的事情:
- 每秒排队较少的作业只会导致相应的故障减少,但仍然会出现故障。
- 在所有对 job.queued 变量的访问中加锁(obj)
- 使用 SmartThreadPool 而不是 defaultThreadPool。问题依旧 持续存在于 STP 的 QueueWorkItem() 中
【问题讨论】:
-
你能在 Windows 上运行它,看看这是不是 Mono 问题吗?
-
在我看来,您可能会时不时地在任务队列上发生争用。当您尝试添加任务时,队列可能被试图从队列中获取工作的线程锁定。
-
再深入一点,我相信这是线程之间争用的问题。分析器显示在 QueueWorkItem 的 Monitor.Exit() 中花费的时间。但我将如何防止这种情况发生?当然,队列周围的锁定不应该持续 60 毫秒!
-
Henk - 我在 Window 的 Mono 2.6 版本上运行它。我不能交换 Mono,因为它是更大框架(Unity 引擎)的一部分。
标签: c# multithreading mono threadpool queueuserworkitem