我有一个有时运行速度很慢的程序。
我尝试了 Teleriks Justtrace 来找出可能导致应用程序挂起的原因。
一个非 UI 线程(因此我相信这不是真正的挂起原因)执行异步。获取对象(入队工作项)并将其从队列中取出来做一些工作。
入队:
public void EnqueueObject(WorkUnit workunit)
{
try
{
workUnits.Add(workunit);
}
catch (Exception ex)
{
/handle exception
}
}
出队:
public WorkUnit Dequeue()
{
try
{
WorkUnit aWorkUnit = null;
workUnits.TryTake(out aWorkUnit, 1000);
return aWorkUnit ;
}
catch (InvalidOperationException ex)
{
//
}
return null;
}
TryTake 用于检查当前工作的中止(而不是 BlockingCollection Complete 方法,它在调用时会抛出一些错误 - 我不想在程序流中使用错误)
调用出队:
while(!isStopped)
{
ProcessWorkItem(Dequeue());
}
到这里为止,它看起来很简单。
问题是,Teleriks JustTrace 显示,“workUnits.TryTake(out aWorkUnit, 1000);”行 占用程序总执行时间的 30%。
怎么会这样?
更多细节表明,在 TryTake System.Threading.Monitor.Wait 内部一直占用 - 我认为 Wait 会发送一个线程进入睡眠状态,因此它在等待期间不会消耗任何东西。思想的错误在哪里?