Frage

Derzeit habe ich diesen Code:

TaskCompletionSource<String> tcs = new TaskCompletionSource<String>();

// ...

process.OutputDataReceived += (sender, e) =>
{
    if (e.Data == null)
    {
        outputWaitHandle.Set();
    }
    else
    {
        tcs.SetResult(e.Data.ToString());
    }
};

// ...

return tcs.Task;

Dann funktioniert der Benutzer dieser Funktion wie:

private async void Foo_Click(object sender, RoutedEventArgs e)
{
    String output = await ExecuteCommand();
}

Das Problem ist nun, dass ich diesen Fehler bekomme:

Eine Ausnahme der ersten Chance von Typ 'system.invalidoperationException' trat in mscorlib.dll auf. Eine nicht behandelte Ausnahme des Typs 'System.invalidoperationException' trat in mscorlib.dll auf

Zusätzliche Informationen: Es wurde versucht, eine Aufgabe in einen endgültigen Zustand zu übergeben, als sie bereits abgeschlossen war

Dieses Problem wird geworfen, wenn ich benutze tcs.SetResult().

War es hilfreich?

Lösung

Das OutputDatarecebed -Ereignis erfolgt in jeder Zeile, die an STDOut geschrieben wurde (und dann ein letztes Mal mit Data == NULL, wenn es fertig ist, wie Sie es anscheinend bereits wissen) .

Angenommen, Sie möchten die gleiche Struktur für den Code beibehalten, sollte sich Ihre sonstige Klausel von tcs.setResult (e.data.tostring ()) ändern; Um die Linie in E.Data in einem StringBuffer oder einer Liste oder was auch immer zu speichern (es enthält nicht die Newline. Wenn Sie dies beibehalten möchten, müssen Sie sie selbst wieder hinzufügen).

Dann wird Ihre "if" -Klausel das tcs.setResult (Stringbuffer.toString ()) erledigen; (oder wie auch immer Sie sich entschieden haben, die Linien zu speichern), bevor Sie den outputWaithandle.set () durchführen

Stellen Sie sicher, dass Sie recirectStandardoutput = true und recirectStandardError = false haben, da sonst der Vorgang blockiert werden kann, wenn er genügend Stderr schreibt, und Sie haben ihn angefordert, um umgeleitet zu werden, aber nicht gelesen. Weitere Informationen dazu suchen Sie nach "Deadlock" im Doc @ http://msdn.microsoft.com/en-us/library/system.diagnostics.process.standarderror.aspx

Andere Tipps

Sie wickeln das ereignisbasierte asynchrone Muster (EAP) ein.

Probieren Sie diesen MSDN -Artikel aus: TPL und herkömmliche .NET -Asynchronprogrammierung

Sobald Sie eine haben Task<T>, du kannst await es.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top