繁体   English   中英

如何在C#中“等待”“ process.OutputDataReceived”事件?

[英]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()时,会引发此问题。

您正在包装基于事件的异步模式(EAP)。

试试这篇MSDN文章: TPL和传统的.NET异步编程

一旦有了Task<T> ,就可以await它。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM