如何解决处置或关闭被杀死的进程
在 process.dispose()
之后调用 process.Close()
或 .Close
(无论是哪一个,'cos .dispose
在 process.Kill()
实现中被调用)有时会挂起应用程序。>
我无法稳定地重现此错误,但有时当 WaitForExit
通过传递给它的超时完成时,应用程序挂起 process.Close()
命令。
请给我建议,这个问题的原因可能是什么?
注意:
- 我见过similar question。但是没有答案&upVoted 评论说,问题的原因可能在细节上,在那个问题上没有提供。所以我添加了更多细节。
- 我也看到了 linked solution,但我不能使用
processstartinfo.UseShellExecute = true;
,因为我需要重定向输出。
抱歉,代码冗长,但我是这样传递的,因为在类似的未回答问题评论员注意到,没有提供足够的细节(正如我上面提到的)
private static async Task<int> RunMethod(string processArguments)
{
// 1. Prepare processstartinfo
processstartinfo startInfo = new processstartinfo();
startInfo.Arguments = processArguments;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.CreateNowindow = true;
startInfo.UseShellExecute = false;
// 2. Create process inside using-block to be disposed
using (var proc = new Process())
{
proc.StartInfo = startInfo;
// 3. Subscribe output streams handlers
proc.OutputDataReceived += (sender,outputLine) => { HandleMessage(outputLine); };
proc.ErrorDataReceived += (sender,errorLine) => { HandleMessage(errorLine); };
// 4. Start process
if (!proc.Start())
{
proc.Close();
return -1;
}
// 5. Start the asynchronous read of the standard output stream.
proc.BeginoutputReadLine();
proc.BeginErrorReadLine();
// 6. Waiting process to exit with timeout on threadpool to not block UI thread
// Re#er warns me "captured variable `proc` is disposed in the outer scope". But I think it's Ok,'cos we're awaiting this task inside using block (in next line)
var waitingProcesstask = Task.Run(() => proc.WaitForExit(TIMEOUT),_cancelToken);
bool hasExited = await waitingProcesstask;
// 7. Stop reading streams
// Not sure,these 2 CalncelXxxRead methods are needed. But hope it won't hurt at least
proc.CancelErrorRead();
proc.CancelOutputRead();
// 8. If !hasExited (i.e. TIMEOUT is reached) we kill the process
if (!hasExited)
{
Logger.Debug("0. Before Kill()");
proc.Kill();
proc.Refresh(); // not sure,it's needed
}
// If uncomment next 2 lines,then problem moves here from end of using block
//proc.Close();
//Logger.Debug("1. after .Close call"); // <------------------ This log we don't see sometimes
Logger.Debug("2. last inside using-block");
} // end of using block
Logger.Debug("3. after using-block"); // <------------------ This log we don't see sometimes (if `.Close` wasn't called before)
return 0;
}
解决方法
我已经解决了我的问题。问题是:我的进程偶尔**会产生子守护进程,它可以永远工作。如果父流被重定向,子进程(按设计)总是继承重定向的输出流。
另一方面,.Kill()
不会杀死子进程 - 仅针对它被调用。 (直到 .Net 5.0,其中 .Kill(bool)
解决了这个问题)。
所以 .Dispose()
或 .Close()
永远不会完成,'cos 等待释放由无限子进程持有的输出流。
弄清楚发生了什么是非常有趣的冒险 =)
**) - 这就是复制非常不稳定的原因
PS:感谢@Blindy 为我指明了非常接近问题真正原因所在的方向。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。