2012-03-28 10 views
8

Ich habe eine Frage bezüglich der Fehlerbehandlung der .NET Task Parallel Library. In welchen Fällen wird eine AggregateException mehr als 1 innere Ausnahme enthalten? Ich weiß, das kann zum Beispiel passieren. beim Aufruf Task.WaitAll(anArrayOfTasks), und 2 oder mehr Aufgaben werfen eine Ausnahme, aber gibt es andere Fälle (d. h. kann es möglich sein, dass, wenn nur warten auf 1 Aufgabe zu beenden, erhalten Sie mehr als 1 innere Ausnahmen)?Wann kann eine AggregateException mehr als 1 innere Ausnahme enthalten?

+0

Nicht verwandt mit Parallelbibliothek. Angenommen, Sie haben eine Methode, um eine Liste von Dateien zu löschen, einige sind jedoch gesperrt. Sie können eine 'AggregateException' verwenden, um die gesperrten Dateien erneut zu löschen und den Rest der Dateien zu löschen. – nalply

Antwort

4

Eine Task kann eine Aggregatausnahme auslösen, die inhärent mehrere innere Ausnahmen enthalten kann. Dies bedeutet, dass Sie bei der Arbeit mit Aufgaben immer eine Sammelausnahme mit mehreren inneren Ausnahmen berücksichtigen sollten. Selbst wenn Sie Task.WaitAll nicht verwenden, wartet die Aufgabe, auf die Sie warten, möglicherweise intern auf mehrere Teilaufgaben. Alternativ kann die Aufgabe, auf die Sie warten, möglicherweise mehrere Ausnahmen zurückgeben. Sie können einfach nicht als Anrufer wissen.

+0

Ich stimme zu, dass Sie im allgemeinen Fall davon ausgehen sollten, dass Sie eine Liste von Ausnahmen erhalten und Ihre Fehlerbehandlung als solche entwerfen. Ich möchte nur wissen, ob die Behandlung einer einzelnen asynchronen Aufgabe, die nicht von anderen asynchronen Aufgaben abhängig ist, jemals erstellt wird eine Situation, in der mehr als 1 Ausnahme übergeben wird. – scripni

+0

Macht vielleicht nur. Es ist jedoch nicht sehr wahrscheinlich. WENN die innere Aufgabe auf mehrere untergeordnete Aufgaben wartet. Es wird eine neue AggregateException erstellt, die 1 AggregateException enthält, die mehrere (möglicherweise aggregierte!) Innere Ausnahmen enthält. Daher ist es immer eine gute Methode, die Flatten-Methode über die AggregateException aufzurufen, um alle Ausnahmen zu erhalten und sie als Sammlung zu behandeln. – Polity

+0

Wie würden Sie in diesem Fall die Fehler an die Benutzeroberfläche weitergeben? Wenn Sie eine Operation ausführen, können Sie normalerweise zwei Ergebnisse erzielen, entweder einen Erfolg oder einen Fehler. Das Entwerfen einer Benutzeroberfläche zur impliziten Behandlung von Fehlerlisten erscheint meiner Meinung nach verwirrend, und zwei Fälle (ein Fehler für einen und mehrere Fehler) scheinen die Dinge zu komplizieren. Ich dachte daran, in der Benutzeroberfläche immer nur eine Ausnahme zu behandeln und alle Ausnahmen zu protokollieren (und dem Benutzer eine Nachricht zu präsentieren, um das Fehlerprotokoll für ex zu überprüfen). – scripni

5

Dies kann vorkommen, wenn Sie eine "übergeordnete" Aufgabe und eine oder mehrere "untergeordnete" Aufgaben haben, die an die übergeordnete Gruppe angehängt sind. Dies bedeutet, dass die übergeordnete Aufgabe nur dann beendet wird, wenn alle untergeordneten Aufgaben abgeschlossen sind und die Ausnahmen von untergeordneten Aufgaben ebenfalls an die übergeordnete Aufgabe weitergegeben werden.

Nehmen Sie zum Beispiel den folgenden Code:

var task = Task.Factory.StartNew(
    () => 
    { 
     Task.Factory.StartNew(
      () => { throw new Exception("inner"); }, 
      TaskCreationOptions.AttachedToParent); 

     throw new Exception("outer"); 
    }); 

Wenn Sie Wait() auf diese Aufgabe, es eine AggregateException thows, das wie folgt aussieht:

  • AggregateException
    • Exception: äußere
    • AggregateException
      • Exception: Innen

Wenn Sie möchten nicht, dass es AggregateException s innerhalb AggregateException s enthalten können, können Sie the Flatten() method verwenden. Es gibt auch eine andere Methode, die für die Verarbeitung von AggregateException s: Handle() verwendet werden kann.

+0

Danke für die Antwort, +1 für die Erwähnung der Handle() Methode, wusste ich nicht darüber. – scripni

Verwandte Themen