我是.net中的线程模型的新手.你会用什么来:
启动一个处理文件的进程(process.StartInfo.FileName = fileName;)
等待用户关闭进程或在一段时间后放弃该线程
如果用户关闭了该进程,请删除该文件
启动进程并等待应该在与主线程不同的线程上完成,因为此操作不应该影响应用程序.
例:
我的应用程序生成一个HTML报告.用户可以右键单击某处并显示"查看报告" - 现在我在临时文件中检索报告内容并启动处理html文件的进程,即默认浏览器.问题是我无法清理,即删除临时文件.
"等待必须是异步的" - 我不是想搞笑,但这不是一个矛盾吗?但是,由于您正在开始Process
,该Exited
活动可能会有所帮助:
ProcessStartInfo startInfo = null; Process process = Process.Start(startInfo); process.EnableRaisingEvents = true; process.Exited += delegate {/* clean up*/};
如果你想实际等待(超时等),那么:
if(process.WaitForExit(timeout)) { // user exited } else { // timeout (perhaps process.Kill();) }
对于等待异步,也许只是使用不同的线程?
ThreadPool.QueueUserWorkItem(delegate { Process process = Process.Start(startInfo); if(process.WaitForExit(timeout)) { // user exited } else { // timeout } });
添加这个旧问题的高级替代方案.如果要等待进程退出而不阻塞任何线程并仍然支持超时,请尝试以下操作:
public static TaskWaitForExitAsync(this Process process, TimeSpan timeout) { ManualResetEvent processWaitObject = new ManualResetEvent(false); processWaitObject.SafeWaitHandle = new SafeWaitHandle(process.Handle, false); TaskCompletionSource tcs = new TaskCompletionSource (); RegisteredWaitHandle registeredProcessWaitHandle = null; registeredProcessWaitHandle = ThreadPool.RegisterWaitForSingleObject( processWaitObject, delegate(object state, bool timedOut) { if (!timedOut) { registeredProcessWaitHandle.Unregister(null); } processWaitObject.Dispose(); tcs.SetResult(!timedOut); }, null /* state */, timeout, true /* executeOnlyOnce */); return tcs.Task; }
同样,与接受的答案相比,这种方法的优势在于您不会阻止任何线程,从而减少了应用程序的开销.