Gestion des exceptions de multithreading asynchrone?

Je souhaite avoir une approche de traitement des exceptions dans ma programmation asynchrone (beginInvoke / endInvoke) dans laquelle si l’un des threads (beginInvoke) échoue, je souhaite que tous les autres threads de traitement asynchrone ne fonctionnent plus. Veuillez suggérer une solution?, Ci-dessous, je joins mon exemple de code également:

public List SendMailAsynch(List requestDto) { List resultDto = new List(); List asyncResults = new List(); foreach (ThreadRequestDto t in requestDto) { //Create a delegate. DoSomeAsynchWorkDelegate del = new DoSomeAsynchWorkDelegate(DoSomeAsynchWork); // Initiate the asynchronous call IAsyncResult a = del.BeginInvoke(t,null, del); //IAsyncResult a = del.BeginInvoke(t, null,null); asyncResults.Add(a); } foreach (IAsyncResult ar in asyncResults) { // wait for each one to complete, then call EndInvoke, passing in the IAsyncResult. // We cast ar.AsyncState to a DoSomeAsynchWorkDelegate, as we passed it in as the second parameter to BeginInvoke. ar.AsyncWaitHandle.WaitOne(); //AsyncState property of IAsyncResult is used to get the delegate that was used to call that method DoSomeAsynchWorkDelegate del = (DoSomeAsynchWorkDelegate)ar.AsyncState; // Call EndInvoke to get the result. Add the result to the list of items. resultDto.Add(del.EndInvoke(ar)); } return resultDto; } 

La meilleure solution consiste probablement à utiliser un ManualResetEvent partagé.

Par exemple:

 class MyClass { private ManualResetEvent workFailedEvent = new ManualResetEvent(false); public List SendMailAsynch(List requestDto) { workFailedEvent.Reset(); // --- The rest of your code as written in your post --- } private void DoAsyncWorkFirst() { try { for (int i = 0; i < 10000; i++) { if (workFailedEvent.WaitOne(0, true)) { break; } // -- Do some work here --- } } catch (MyException) { workFailedEvent.Set(); } } private void DoAsyncWorkSecond() { try { for (int j = 0; j < 20000; j++) { if (workFailedEvent.WaitOne(0, true)) { break; } // --- Do some different work here --- } } catch (MyOtherException) { workFailedEvent.Set(); } } } 

La partie intéressante ici est l'appel à WaitOne (0, true) . Si vous utilisez un délai d'attente de 0, le fil ne sera pas bloqué. Etant donné que le ManualResetEvent est synchronisé par le système d'exploitation, cet appel de méthode est un moyen pratique de rechercher un signal sans avoir à se soucier des conditions de concurrence ou à mettre en œuvre votre propre locking.