【发布时间】:2012-12-31 01:34:17
【问题描述】:
我正在编写一个应用程序,其中我有一个在BackgroundWorker 中运行的进程。我想支持从用户界面取消,但我没有看到一个简单的方法来做到这一点。
Process 实际上是一个运行时间相当长的命令行 exe。输出通过 Progress.OutputDataReceived 事件异步重定向,并用于向 GUI 报告进度。
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
using (var process = new Process())
{
//...
process.Start()
//...
process.WaitForExit();
}
}
private void CancelWorker()
{
worker.CancelAsync();
// where to actually listen for the cancellation???
}
除了StandardInput 之外,似乎没有办法让进程“侦听”来自主线程的任何输入,但除非应用程序本身响应特定输入中止。
有没有办法根据来自主线程的取消请求取消进程?
为了我在进程中运行的EXE,我可以调用Process.Close()退出而没有任何副作用,但是Process对象只有worker_DoWork()方法知道,所以我'出于取消目的,我需要跟踪 Process 实例...这就是为什么我希望可能有更好的方法。
(如果重要的话,我的目标是 .NET 3.5 以解决兼容性问题。)
【问题讨论】:
-
您在 BG 工作人员中启动进程是否有原因?这通常是一个不需要很长时间的调用(正在启动的程序可能需要一段时间才能加载,但这将在它自己的进程中)。
-
其实不是在后台worker中,而是在自定义的Async方法中,
BackgroundWorker似乎更容易描述这种情况。但原因是这是在后台线程中运行的更大进程的一部分。 -
CancelAsync 将不起作用,因为线程在几毫秒内完成了它的工作,除非您在该
DoWork方法中有一些繁重的负载。尽管using是一种很好的做法,但由于您需要能够从代码中的其他位置访问Process,您可以有一个类级别的变量来保存Process并调用Process.Close。只要记住当您的线程返回或不再需要该进程时对该进程调用Dispose。 -
Process中运行的 exe 是运行时间相当长的命令行工具,我试图从我的应用程序中执行它……平均而言,它可能需要 15 分钟或更长时间才能完成。它以异步方法运行的原因之一是允许进行进度报告。我无法直接从process_OutputDataReceived事件处理程序报告进度,因为它位于不同的线程上,因此异步方法似乎是一个合乎逻辑的选择。
标签: c#