C# System.Diagnostics.Process 重定向大量数据的标准输出
我从 .NET 应用程序运行一个 exe,并尝试将标准输出重定向到流读取器。问题是当我执行
myprocess.exe >> 时out.txt
out.txt 接近 14mb。 当我执行命令行版本时,速度非常快,但是当我从 csharp 应用程序运行该进程时,速度非常慢,因为我相信默认的流读取器每 4096 字节刷新一次。
有没有办法更改 Process 对象的默认流读取器?
I running an exe from a .NET app and trying to redirect standard out to a streamreader. The problem is that when I do
myprocess.exe >> out.txt
out.txt is close to 14mb.
When I do the command line version it is very fast but when I run the process from my csharp app it is excruciatingly slow because I believe the default streamreader flushes every 4096 bytes.
Is there a way to change the default stream reader for the Process object?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我没有尝试过,但看起来异步方法可能会提供更好的性能。不要使用 process.StandardOutput,而是尝试以下方法:
I haven't tried, but it looks like the asynchronous methods may offer better performance. Instead of using
process.StandardOutput
, try this method instead:编辑:刚刚意识到我回答了错误的问题。就我而言,标准输出缓冲区已满,并且 WaitForExit() 永远阻塞,因为尚未从缓冲区读取任何内容。因此,如果您遇到这个问题,那么这里有一个解决方案。 ;)
这是我使用 C# 的第一天,所以请理解这可能不是最好的解决方案,并且可能并不总是有效。但它在我测试过的 2x 中有效。 ;) 这是同步的,只需在 WaitForExit() 之前开始将重定向的 stdout/stderr 写入文件即可。这样,WaitForExit() 就不会阻塞等待标准输出缓冲区被清空。
Edit: Just realized I'm answering the wrong question. In my case the stdout buffer was full and WaitForExit() was blocking forever, because nothing was reading from the buffer yet. So if you have THAT problem, then here's a solution. ;)
This is my first day with C# so please understand that this might not be the best solution, and might not always work. But it works in the 2x I've tested it. ;) This is synchronous, just start start writing the redirected stdout/stderr to the file before you WaitForExit(). This way WaitForExit() won't block waiting for the stdout buffer to be emptied.
是的,差不多是这样。 有一个用于存储进程输出的缓冲区,在常见的 CRT 实现中通常在 1 到 4KB 之间。一个小细节:该缓冲区位于您启动的进程中,而不是 .NET 程序中。
当您重定向到文件时,不需要发生任何特别的事情,CRT 直接写入它。但是,如果您重定向到 .NET 程序,则输出将从缓冲区进入管道。然后将线程切换到您的程序,以便您可以清空管道。来回好700次了。
是的,不快。不过很容易修复,在您正在运行的程序中调用 setvbuf() 来增加 stdout 和 stderr 输出缓冲区大小。话又说回来,这需要拥有该程序的源代码。
预计会出现问题:也许您应该使用 cmd.exe /c 重定向到文件,然后读取该文件。
Yes, that's about right. There is a buffer that stores the process output, usually between 1 and 4KB in the common CRT implementations. One small detail: that buffer is located in the process you start, not the .NET program.
Nothing very special needs to happen when you redirect to a file, the CRT directly writes it. But if you redirect to your .NET program then output goes from the buffer into a pipe. Which then takes a thread switch to your program so you can empty the pipe. Back and forth a good 700 times.
Yes, not fast. Easily fixed though, call setvbuf() in the program you are running to increase the stdout and stderr output buffer sizes. Then again, that takes having the source code of that program.
Anticipating a problem with that: maybe you ought to use cmd.exe /c to get the redirection to a file, then read the file.
Process 类直接公开标准输出流,因此您应该能够以您喜欢的任何速度读取它。最好以小块的形式读取它并避免调用 ReadToEnd。
例如:
The Process class exposes the stdout stream directly, so you should be able to read it at whatever pace you like. It's probably best to read it in small chunks and avoid calling ReadToEnd.
For example:
这对我来说很有效:
This worked out for me: