0

現在、私はこのコードを持っています:

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;

次に、この関数のユーザーは次のように機能します。

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

今問題は、このエラーが発生していることです:

タイプ 'System.InvalidOperationException' の初回例外が mscorlib.dll で発生しました タイプ 'System.InvalidOperationException' の未処理の例外が mscorlib.dll で発生しました

追加情報: タスクが既に完了しているときに、タスクを最終状態に移行しようとしました

を使用すると、この問題がスローされますtcs.SetResult()

4

2 に答える 2

2

イベントベースの非同期パターン ( EAP ) をラップしています。

この MSDN の記事を試してください: TPL と従来の .NET 非同期プログラミング

を取得したらTask<T>、それを実行できawaitます。

于 2012-02-19T12:10:36.467 に答える
1

OutputDataReceived イベントは、stdout に書き込まれた各行で発生します (そして、既にご存知のように、Data == null が完了すると、最後に発生します)。 SetResult を複数回実行しようとしているため、その例外が発生します。 .

コードの同じ構造を維持したいと仮定すると、else 句は tcs.SetResult(e.Data.ToString()); から変更する必要があります。行を e.Data の StringBuffer や List などに保存します (改行は含まれないため、それを保持したい場合は、自分で追加する必要があります)。

次に、「if」句が tcs.SetResult(stringBuffer.ToString()); を実行します。(または、行を保存することにしました) outputWaitHandle.Set() を実行する前に

RedirectStandardOutput = true および RedirectStandardError = false であることを確認してください。そうしないと、プロセスが十分な stderr を書き込み、リダイレクトするように要求したが、それを読み取っていない場合、プロセスがブロックされる可能性があります。詳細については、ドキュメント @ http://msdn.microsoft.com/en-us/library/system.diagnostics.process.standarderror.aspxで「デッドロック」を検索してください。

于 2012-02-19T18:46:45.277 に答える