時々かなり遅く実行されるプログラムがあります。
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内で常に時間がかかることがわかります。待機するとスレッドがスリープ状態になると思ったので、待機中に何かを消費することはありません。思考の誤りはどこにありますか?