Question

À l'heure actuelle, j'ai ce 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;

Ensuite, l'utilisateur de cette fonction fonctionne comme:

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

Maintenant, le problème est que je reçois cette erreur:

Une première chance exception du type 'System.InvalidOperationException' produite dans mscorlib.dll Une exception non gérée du type 'System.InvalidOperationException' produite dans mscorlib.dll

Informations complémentaires: Tentative de transition une tâche à un état final quand il avait déjà terminé

Ce problème est jeté quand je l'utilise tcs.SetResult().

Était-ce utile?

La solution

The OutputDataReceived event happens on each line written to stdout (and then a final time with Data == null when it's done, as you seem to already know), so you're getting that exception because you're trying to do SetResult multiple times.

Assuming you want to keep the same structure for the code, your else clause should change from tcs.SetResult(e.Data.ToString()); to storing the line in e.Data in a StringBuffer or List or whatever (it doesn't include the newline, so if you want to preserve that, you'll need to add it back yourself).

Then your 'if' clause will do the tcs.SetResult(stringBuffer.ToString()); (or however you decided to store the lines) before doing the outputWaitHandle.Set()

Make sure you have RedirectStandardOutput = true and RedirectStandardError = false since otherwise the process may block if it writes enough stderr and you requested it to get redirected but haven't read it. For details about that, search for 'deadlock' in the doc @ http://msdn.microsoft.com/en-us/library/system.diagnostics.process.standarderror.aspx

Autres conseils

You're wrapping the Event-based Asynchronous Pattern ( EAP ).

Try this MSDN article: TPL and Traditional .NET Asynchronous Programming

Once you have a Task<T>, you can await it.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top