c# - 如何在没有死锁的情况下正确读取 c# 进程标准错误流?

标签 c# .net-core

根据 MSDN,我真的感觉自己在遵循最佳实践.但我很可能遗漏了一些东西,因为我的代码在从这一行继续后挂起:string errorOutput = cmd.StandardError.ReadToEnd();。我做错了什么?

        var batchfile = File.OpenWrite("run.bat");
        StreamWriter writer = new StreamWriter(batchfile);
        writer.Write("dotnet run" + '\n');
        //writer.Write("set /p temp=\"Hit enter to continue\"" + '\n');
        writer.Close();

        var cmd = new Process();
        cmd.StartInfo.FileName = batchfile.Name;
        cmd.StartInfo.UseShellExecute = false;
        cmd.StartInfo.RedirectStandardError = true;

        cmd.Start();
        string errorOutput = cmd.StandardError.ReadToEnd();
        cmd.WaitForExit();

        var outputfile = File.OpenWrite("run_errorOut.txt");
        StreamWriter outputWriter = new StreamWriter(outputfile);
        outputWriter.Write(errorOutput);
        outputWriter.Close();

如果有帮助:目前这段代码正在 dotnetcore2.2 应用程序(其目标框架是“netcoreapp2.2”)的 xunit 测试中运行。

最佳答案

所以不久前我遇到了一个非常相似的问题,几乎完全一样,我发现的是:

  • 尝试在没有任何可读 block 的情况下读取 StandardError/Output block ,直到有可读的东西为止(如果没有任何内容可读则死锁 - 例如进程已退出)
  • cmd.HasExited 在读取 StandardError/Output 之前为 false,因此无法用于检测何时完成(然后读取 StandardError/Output)

我发现最可靠的方法是在 Process 上使用提供的事件:

var outData = new StringBuilder();
var errData = new StringBuilder();    

cmd.OutputDataReceived += (sender, args) => outData.Append(args.Data ?? string.Empty);
cmd.ErrorDataReceived += (sender, args) => errData.Append(args.Data ?? string.Empty);

然后在 cmd.Start() == true 之后:

cmd.BeginErrorReadLine();
cmd.BeginOutputReadLine();

开始触发事件。

进程退出后,您可以在 StringBuilder 上调用 .ToString() 来获取数据:

Console.WriteLine(outData.ToString());
Console.WriteLine(errData.ToString());

(注意 .ToString() 在使用 Console.WriteLine 时可以是隐式的)

关于c# - 如何在没有死锁的情况下正确读取 c# 进程标准错误流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56571693/

相关文章:

c# - DryIoc 构造函数参数重用

c# - System.String[*] 代表什么?

c# - 使用 csvHelper 处理 csv 文件中的无效条目

azure - 如何解决 azure 发布的 Blazor 应用程序上的 XMLHttpRequest 错误

c# - Startup.cs 返回错误的环境

c# - 我的 Azure 开发环境总是将我重定向到错误页面

c# - 带有内部连接的 SQL Server NULL 值

reactjs - 识别 SPA 和 .NET Core 3 的角色

azure - 如何诊断 AspNetCore 应用程序未在 Azure 应用服务上启动?

.net-core - 如何通过 NLog 记录 Entity Framework Core 操作