Дубликат: Как перехватить исключения из 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
}
Но весь пакет должен обрабатываться транзакционно, т. Е. Вывод родительского потока должен выполняться только в том случае, если все дочерние потоки были успешными. Я закодировал дочерний поток, чтобы он выдавал пользовательское исключение, когда оно не удавалось, но я обнаружил, что это вызывает сбой родительского потока, так как эти исключения не могут быть «перехвачены» в родительском потоке ...
Я читал о выбросе UnHandledExceptionEvent CLR, когда это происходит, но мне нужно «обработать» это исключение в методе, в котором эти дочерние потоки помещаются в очередь и порождаются, чтобы управлять немедленной последующей обработкой на основе успеха триада ребенка ... Как мне это сделать?