私は、マルチスレッド形式のアプリケーションを持っており、これは、問題の一部が設計された方法です。ManualResetEvent - WAITONE()はいくつかの点でスレッドを解放していないようだ
スレッド2(BatchPreviewAssistantクラス)を待っていますプライマリインターフェイスのスレッドは、画像を読み込むタスクを渡す。タスクが受信されると、BatchPreviewAssistantはタスクをN = 5 waiting PrimaryLoaderスレッドに割り当て、それらを有効にします。 PrimaryLoaderは、_startEventと_endEventの2つの手動リセットイベントを使用して開始/停止された無限ループとして実行されています。また、PrimaryLoadersからBatchPreviewAssistantへの処理の終了を知らせるためのN個の手動リセットイベント_parentSyncEventの配列があります。
通常、各PrimaryLoaderは_startEvent.WaitOne()で待機しています。 BatchPreviewAssistantがそれらをアクティブにしてRunPrimaryLoaders()を実行すると、まず_endEventおよび_parentSyncEventsをリセットしてから_startEventを設定します。 各PrimaryLoaderが完了すると、すべての5が設定されるまで_ParentSyncEventに独自のイベントが設定されます。この時点で、すべてのPrimaryLoaderは_endEventに到達します。 WAITONE()と待っ今_parentSyncEventsは継続するBatchPreviewAssistantを可能にし、すべてのセットです はBatchPreviewAssistantは_startEventをリセットしてからPrimaryLoadersを解放_endEventを設定し、彼らは、ループの最初に戻ってくる
BatchPreviewAssistant:。。。
private void RunPrimaryLoaders()
{
BatchPreviewThreadsLogger.WriteLog(Common.LogLevel.Debug1, "RunPrimaryLoaders()");
ResetEvents(_parentSyncEvents);
_endEvent.Reset();
_startEvent.Set();
// Primary Loader loops restart
BatchPreviewThreadsLogger.WriteLog(Common.LogLevel.Debug2, "WaitHandle.WaitAll(_parentSyncEvent");
if (!WaitHandle.WaitAll(_parentSyncEvents, 20 * 1000))
{
throw new TimeoutException("WaitAll(_parentSyncEvent) in ProcessCurrentCommand");
// TODO: Terminate?
}
BatchPreviewThreadsLogger.WriteLog(Common.LogLevel.Message3, "Primary loading is complete");
_startEvent.Reset();
_endEvent.Set();
bool isEndEventSet = _endEvent.WaitOne(0);
BatchPreviewThreadsLogger.WriteLog(Common.LogLevel.Debug2, "isEndEventSet?" + isEndEventSet.ToString());
}
PrimaryLoader:
public void StartProc(object arg)
{
while (true)
{
BatchPreviewThreadsLogger.WriteLog(Common.LogLevel.Debug2, "Primary Loader: _startEvent.WaitOne()");
_startEvent.WaitOne();
try
{
BatchPreviewThreadsLogger.WriteLog(Common.LogLevel.Message4, "Primary Loader is processing entry:" + processingEntry.DisplayPosition.ToString());
}
catch (Exception ex)
{
BatchPreviewThreadsLogger.WriteLog(Common.LogLevel.Error, "Exception in PrimaryImageLoader.StartProc:" + ex.ToString());
}
_parentSyncEvent.Set();
BatchPreviewThreadsLogger.WriteLog(Common.LogLevel.Debug2, "Primary Loader: _endEvent.WaitOne()");
_endEvent.WaitOne();
}
}
このコードは、何百ものループを作成するのには非常に効果的ですが、特にストレステスト中に問題が発生します。 BatchPreviewAssistantが_endEvent.Set()を設定すると、PrimaryLoadersのどれもが_endEvent.WaitOne()で解放されません。 BatchPreviewAssistantをチェックして、イベントが実際に設定されていることがわかりますが、PrimaryLoadersは解放されません。
[10/27/2011;21:24:42.796;INFO ] [42-781:16]Primary Loader: _endEvent.WaitOne()
[10/27/2011;21:24:42.796;INFO ] [42-781:18]Primary Loader: _endEvent.WaitOne()
[10/27/2011;21:24:42.796;INFO ] [42-781:19]Primary Loader: _endEvent.WaitOne()
[10/27/2011;21:24:42.843;INFO ] [42-843:15]Primary Loader: _endEvent.WaitOne()
[10/27/2011;21:24:42.937;INFO ] [42-937:17]Primary Loader: _endEvent.WaitOne()
[10/27/2011;21:24:42.937;INFO ] [42-937:14]Primary loading is complete
[10/27/2011;21:24:42.937;INFO ] [42-937:14]isEndEventSet?True
このようなデザインで問題を引き起こす可能性のある問題はありますか? 私は回避策として試してみる方法がいくつかありますが、この問題が何か問題であるかどうかは分かります。
プライマリローダーを初期化して起動する方法についてもinformatinを提供しています。私はサンプルがあまりにも忙しいとフォローするのは困難であることを同意するだろう :
private PrimaryImageLoader[] _primaryImageLoaders;
_primaryImageLoaders = new PrimaryImageLoader[N]
for (int i = 0; i < _primaryImageLoaderThreads.Length; i++)
{
_parentSyncEvents[i] = new AutoResetEvent(false);
_primaryImageLoaders[i] = new PrimaryImageLoader(i, _parentSyncEvents[i],
_startEvent, _endEvent,
_pictureBoxes, _asyncOperation,
LargeImagesBufferCount);
_primaryImageLoaderThreads[i] = new Thread(new ParameterizedThreadStart(_primaryImageLoaders[i].StartProc));
_primaryImageLoaderThreads[i].Start();
}
は、いくつかの無関係なコードがサンプル
に、コメントを追加し簡素化するために削除されていることに注意してください。これは、それは一言で言えばです:
Thread 2:
private void RunPrimaryLoaders()
{
_endEvent.Reset();
_startEvent.Set();
_startEvent.Reset();
_endEvent.Set();
bool isEndEventSet = _endEvent.WaitOne(0);
}
Threads 3-7:
public void StartProc(object arg)
{
while (true)
{
_startEvent.WaitOne();
_endEvent.WaitOne(); // This is where it can't release occasionally although Thread 2 checks and logs that the event is set
}
}
あなたは競争状態を持っているようです... TTジョークを除いて、あなたの例はあまりにも長く、従うのが複雑です。デザインの実際の目的は何ですか? – Kiril