我编写了一个实用程序,用于启动和停止特定进程。现在,在测试它时,它似乎阻止了它产生的过程!
它使用命名系统事件(参见System.Threading.EventWaitHandle)。在开始该过程之后,它等待设置事件:
private static int StartRavenDB(string fileName, string workingDirectory, string arguments)
{
var process = new Process
{
StartInfo =
{
FileName = fileName,
WorkingDirectory = workingDirectory,
Arguments = arguments,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardInput = true,
RedirectStandardOutput = true
}
};
process.Start();
var eventWaitHandle = new EventWaitHandle(false, EventResetMode.ManualReset, "StartStopRavenDBUtility");
eventWaitHandle.Reset();
eventWaitHandle.WaitOne();
process.StandardInput.WriteLine("q");
process.WaitForExit();
return process.ExitCode;
}
现在,启动的RavenDB进程是一个侦听localhost:8080
的Web服务器。
使用上述实用程序启动该过程后不久,该过程不响应Web请求。它保持超时。一旦我杀死了实用程序进程,一切都开始正常工作。
为了记录,我100%没有设置EventWaitHandle - RavenDB进程就在那里,但它没有表现出来。
我不知道发生了什么或为什么,这是一个完全独立的过程。是什么导致了这个问题?
答案 0 :(得分:1)
您应该订阅OutputDataReceived
事件或至少读取重定向的标准输出,以避免阻塞线程。来自documentation:
这些依赖项可能会导致死锁条件。当来电者 从子进程的重定向流中读取,它是依赖的 对孩子。调用者等待读操作直到孩子 写入流或关闭流。 当孩子处理 写入足够的数据来填充其重定向流,它依赖于 父母。子进程等待下一个写操作,直到 父级从完整流中读取或关闭流。 当调用者和子进程等待时,会导致死锁条件 彼此完成一项操作,都不能继续。您可以 通过评估调用者和调用者之间的依赖关系来避免死锁 儿童过程。