[英]How to “await” “process.OutputDataReceived” event in C#?
目前,我有以下代码:
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();
}
现在的问题是我收到此错误:
mscorlib.dll中发生类型'System.InvalidOperationException'的第一次机会异常mscorlib.dll中发生类型'System.InvalidOperationException'的未处理异常
附加信息:尝试将任务完成后将其转换为最终状态
当我使用tcs.SetResult()
时,会引发此问题。
OutputDataReceived事件发生在写入stdout的每一行上(然后完成的最后一次时间是Data == null,正如您已经知道的那样),因此您将收到该异常,因为您尝试多次执行SetResult 。
假设您要为代码保留相同的结构,则else子句应从tcs.SetResult(e.Data.ToString())更改。 将行存储在StringBuffer或List或任何其他形式的e.Data中(不包括换行符,因此,如果要保留换行符,则需要自己重新添加)。
然后,您的“ if”子句将执行tcs.SetResult(stringBuffer.ToString());。 (或者您决定存储行),然后再执行outputWaitHandle.Set()
确保您具有RedirectStandardOutput = true和RedirectStandardError = false,因为否则,如果该过程写入足够的stderr并且您请求对其进行重定向但还没有读取,则该过程可能会阻塞。 有关此信息的详细信息,请在文档@ http://msdn.microsoft.com/zh-cn/library/system.diagnostics.process.standarderror.aspx中搜索“死锁”
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.