修身养性,知行合一

  • 首页
  • 爱码
    • 系统
    • 数据库
    • JavaScript
    • CSharp
    • Python
  • 生活
    • 文化
    • 美食
  • 杂谈
  • 关于
修身养性,知行合一
码字,杂谈
  1. 首页
  2. 爱码
  3. CSharp
  4. 正文

C#使用Process的StandardOutput遇到阻塞的问题及解决方案

2019年10月30日 8144点热度 1人点赞 0条评论

项目中使用ffprobe插件读取视频信息,不用想,肯定要是用Process创建进程,然后使用StandardOuput接收输出。然而在测试的时候,发现程序一直卡在ffprobe的进程。

我试过的方案

1、看到有人说需要把p.StandardOutput.ReadToEnd()放到p.WaitForExit()后面,还信誓旦旦的说,如果放在之前,会接收不到任何信息,因为ReadToEnd()是同步函数。

  • 然后我上官方文档查看了一下,确认ReadToEnd()同时支持同步和异步,所以根本不对。而且官方文档也是将p.StandardOutput.ReadToEnd()放到p.WaitForExit()前面使用的。

2、使用StandardError接收信息。有人说试了好长时间,StandardOutput不会接收到任何信息,反而使用StandardError能顺利接收到信息。

  • 我尝试了一下,纯属胡扯。我同样接收不到任何消息。这样做的人是这样解释的:StandardOutput属于同步,StandardError属于异步,所以使用StandardError可以接收信息。根据第一种失败的方案得到的结论,这个方案同样失败。

我的最终解决方案

其实最好的答案就在官方文档中,它的介绍里有一句These synchronous read operations do not complete until the associated Process writes to its StandardOutput stream, or closes the stream.。

于是在写完之后,我尝试手动关闭它,然后惊喜的发现,它正常了。。。

string result = String.Empty;
using (Process p = new Process())
{
    p.StartInfo.UseShellExecute = false;  // 如果使用StandardOutput接收,这项必须为false(来自官方文档)
    p.StartInfo.CreateNoWindow = true;  // 是否创建窗口,true为不创建
    p.StartInfo.RedirectStandardOutput = true;  // 使用StandardOutput接收,一定要重定向标准输出,否则会报InvalidOperationException异常
    p.StartInfo.FileName = Path.Combine(ffmpegPath, "ffprobe.exe");  // 设置启动文件路径
    p.StartInfo.Arguments = $" -v error -print_format json -show_streams -show_format \"{Path.GetFullPath(Path.Combine(localPath, videoName))}\"";  // 设置参数
    p.Start();  // 启动进程
    StreamReader reader = p.StandardOutput;  // 创建输出流
    result = reader.ReadToEnd();  // 接收信息
    // 这里注意了,当读取完成,手动关闭输出流,确保流关闭后,进程才会退出。
    reader.Close();  // 关闭输出流
    p.WaitForExit();
    p.Close();
    p.Dispose();
}

嗯,大致就是这样的。

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
标签: csharp
最后更新:2019年10月30日

jeremyjone

这个人很懒,什么都没留下

打赏 点赞
< 上一篇
下一篇 >

文章评论

取消回复

文章目录
  • 我试过的方案
  • 我的最终解决方案
最新 热点 随机
最新 热点 随机
推一个vscode纯黑主题 vue 的递归插槽穿透 Github Pages SPA 重定向 行间距引出的 DOCTYPE 怪异行为 写个小彩蛋 绘制一个可重用的线条阴影
.NET Model名称转换 强制修改Windows时区 JavaScript异步加载图片 JS的console中log和dir的区别 vue 给全局自定义属性添加 ts 类型声明 js 问号链以及双问号的打包问题

(っ•̀ω•́)っ✎⁾⁾ 开心每一天

COPYRIGHT © 2021 jeremyjone.com. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS

京ICP备19012859号-1

京公网安备 11010802028585号