6 Stimmen

Asynchrone Multithreading-Ausnahmebehandlung?

Ich möchte eine Ausnahmebehandlung Ansatz in meiner asynchronen Programmierung (beginInvoke/endInvoke) haben, wobei, wenn einer der Thread (beginInvoke) fehlschlägt, dann möchte ich alle anderen asynchrone Verarbeitung Thread zu stoppen arbeiten. Bitte schlagen Sie einige Lösung?, unten bin ich meine Beispielcode auch anhängen:

public List<ThreadResultDto> SendMailAsynch(List<ThreadRequestDto>  requestDto)
{
    List<ThreadResultDto> resultDto = new List<ThreadResultDto>();
    List<IAsyncResult> asyncResults = new List<IAsyncResult>();

    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;
}

2voto

Aaronaught Punkte 118136

Der beste Weg ist wahrscheinlich die Verwendung eines gemeinsamen ManualResetEvent .

Zum Beispiel:

class MyClass
{
    private ManualResetEvent workFailedEvent = new ManualResetEvent(false);

    public List<ThreadResultDto> SendMailAsynch(List<ThreadRequestDto>  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();
        }
    }
}

Interessant ist hier die Aufforderung an WarteEins(0, wahr) . Wenn Sie ein Timeout von 0 verwenden, wird der Thread nicht blockiert. Da die ManualResetEvent vom Betriebssystem synchronisiert wird, ist dieser spezielle Methodenaufruf eine bequeme Möglichkeit, auf ein Signal zu prüfen, ohne sich um Race Conditions kümmern zu müssen oder ein eigenes Locking zu implementieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X