重複: ThreadPool.QueueUserWorkItem から例外をキャッチする方法は?
複数のデータベースやその他のオフライン リソースを呼び出す多数の独立したリモート呼び出しのために、.Net ThreadPool で複数のデリゲートをキューに入れています。これらの呼び出しを ThreadPool のキューに入れることで、それらを同時に実行し、全体的な待ち時間を最小限に抑えることができます。
private void CompleteAndQueuePayLoads(IEnumerable<UsagePayload> payLoads)
{
List<WaitHandle> waitHndls = new List<WaitHandle>();
foreach (UsagePayload uPyLd in payLoads)
{
ManualResetEvent txEvnt = new ManualResetEvent(false);
UsagePayload uPyLd1 = uPyLd ;
ThreadPool.QueueUserWorkItem(
delegate
{
if (!uPyLd1 .IsComplete)
// IEEDAL.GetPayloadReadings is long running DB call
try { IEEDAL.GetPayloadReadings(uPyLd1 ); }
catch (IEEAccessException iX)
{
log.Write(log.Level.Error,
"IEEWSDAL.CompleteAndQueuePayLoads " +
" Delegate Failed " +
iX.Message, iX);
txEvnt.Set();
throw; // this causes parent thread to crash!
// was going to try Thread.Abort next ...
// Thread.CurrentThread.Abort();
}
UsageCache.PersistPayload(uPyLd1 );
SavePayLoadToProcessQueueFolder(uPyLd1 );
txEvnt.Set();
});
waitHndls.Add(txEvnt);
}
util.WaitAll(waitHndls.ToArray()); //To waitone on > 64 waithandles
}
ただし、バッチ全体をトランザクションで処理する必要があります。つまり、すべての子スレッドが成功した場合にのみ、親スレッドの出力を続行できるようにする必要があります。失敗したときにカスタム例外をスローするように子スレッドをコーディングしましたが、これらの例外は親スレッドで「キャッチ」できないため、これにより親スレッドがクラッシュすることがわかりました...
これが発生したときに CLR によって UnHandledExceptionEvent がスローされることについて読みましたが、これらの子スレッドがキューに入れられて生成されるメソッドでこの例外を「処理」して、子の成功に基づいてすぐに下流の処理を制御する必要があります。 threeads...どうすればいいですか?