gpt4 book ai didi

c# - 使用 .NET Process.Start 运行时进程挂起——怎么了?

转载 作者:IT王子 更新时间:2023-10-29 04:16:04 24 4
gpt4 key购买 nike

我围绕 svn.exe 编写了一个快速而肮脏的包装器来检索一些内容并用它做一些事情,但对于某些输入,它偶尔会重复地挂起并且不会完成。例如,一个调用是 svn list:

svn list "http://myserver:84/svn/Documents/Instruments/" --xml  --no-auth-cache --username myuser --password mypassword

当我只是从命令 shell 执行时,此命令行运行良好,但它卡在我的应用程序中。运行此代码的 C# 代码是:

string cmd = "svn.exe";
string arguments = "list \"http://myserver:84/svn/Documents/Instruments/\" --xml --no-auth-cache --username myuser --password mypassword";
int ms = 5000;
ProcessStartInfo psi = new ProcessStartInfo(cmd);
psi.Arguments = arguments;
psi.RedirectStandardOutput = true;
psi.WindowStyle = ProcessWindowStyle.Normal;
psi.UseShellExecute = false;
Process proc = Process.Start(psi);
StreamReader output = new StreamReader(proc.StandardOutput.BaseStream, Encoding.UTF8);

proc.WaitForExit(ms);
if (proc.HasExited)
{
return output.ReadToEnd();
}

这需要整整 5000 毫秒并且永远不会完成。延长时间没有用。在单独的命令提示符下,它会立即运行,所以我很确定这与等待时间不足无关。然而,对于其他输入,这似乎工作正常。

我也试过在这里运行一个单独的cmd.exe(这里的exe是svn.exe,args是原来的arg字符串),但是还是挂了:

string cmd = "cmd";
string arguments = "/S /C \"" + exe + " " + args + "\"";

我可能在这里搞砸了什么,我该如何调试这个外部进程的东西?

编辑:

我现在正着手解决这个问题。 Mucho 感谢 Jon Skeet 的建议,这确实很管用。不过,由于我是多线程新手,我还有一个关于我处理这个问题的方法的问题。我想要有关改进任何明显缺陷或任何其他愚蠢问题的建议。我最终创建了一个小类,其中包含 stdout 流、一个用于保存输出的 StringBuilder 以及一个用于告知何时完成的标志。然后我使用了 ThreadPool.QueueUserWorkItem 并传入了我的类的一个实例:

ProcessBufferHandler bufferHandler = new ProcessBufferHandler(proc.StandardOutput.BaseStream,
Encoding.UTF8);
ThreadPool.QueueUserWorkItem(ProcessStream, bufferHandler);

proc.WaitForExit(ms);
if (proc.HasExited)
{
bufferHandler.Stop();
return bufferHandler.ReadToEnd();
}

...和...

private class ProcessBufferHandler
{
public Stream stream;
public StringBuilder sb;
public Encoding encoding;
public State state;

public enum State
{
Running,
Stopped
}

public ProcessBufferHandler(Stream stream, Encoding encoding)
{
this.stream = stream;
this.sb = new StringBuilder();
this.encoding = encoding;
state = State.Running;
}
public void ProcessBuffer()
{
sb.Append(new StreamReader(stream, encoding).ReadToEnd());
}

public string ReadToEnd()
{
return sb.ToString();
}

public void Stop()
{
state = State.Stopped;
}
}

这似乎可行,但我怀疑这是不是最好的方法。这合理吗?我可以做些什么来改进它?

最佳答案

一个标准问题:进程可能正在等待您读取其输出。创建一个单独的线程,在等待它退出时从它的标准输出中读取。这有点痛苦,但这很可能就是问题所在。

关于c# - 使用 .NET Process.Start 运行时进程挂起——怎么了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/439617/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com