Bog*_*SFT 36 .net c# multithreading process
我是.net中的线程模型的新手.你会用什么来:
启动进程并等待应该在与主线程不同的线程上完成,因为此操作不应该影响应用程序.
例:
我的应用程序生成一个HTML报告.用户可以右键单击某处并显示"查看报告" - 现在我在临时文件中检索报告内容并启动处理html文件的进程,即默认浏览器.问题是我无法清理,即删除临时文件.
Mar*_*ell 61
"等待必须是异步的" - 我不是想搞笑,但这不是一个矛盾吗?但是,由于您正在开始Process,该Exited活动可能会有所帮助:
ProcessStartInfo startInfo = null;
Process process = Process.Start(startInfo);
process.EnableRaisingEvents = true;
process.Exited += delegate {/* clean up*/};
Run Code Online (Sandbox Code Playgroud)
如果你想实际等待(超时等),那么:
if(process.WaitForExit(timeout)) {
// user exited
} else {
// timeout (perhaps process.Kill();)
}
Run Code Online (Sandbox Code Playgroud)
对于等待异步,也许只是使用不同的线程?
ThreadPool.QueueUserWorkItem(delegate {
Process process = Process.Start(startInfo);
if(process.WaitForExit(timeout)) {
// user exited
} else {
// timeout
}
});
Run Code Online (Sandbox Code Playgroud)
Chr*_*lum 18
添加这个旧问题的高级替代方案.如果要等待进程退出而不阻塞任何线程并仍然支持超时,请尝试以下操作:
public static Task<bool> WaitForExitAsync(this Process process, TimeSpan timeout)
{
ManualResetEvent processWaitObject = new ManualResetEvent(false);
processWaitObject.SafeWaitHandle = new SafeWaitHandle(process.Handle, false);
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
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;
}
Run Code Online (Sandbox Code Playgroud)
同样,与接受的答案相比,这种方法的优势在于您不会阻止任何线程,从而减少了应用程序的开销.
.NET 5 引入了新的 API Process.WaitForExitAsync,它允许异步等待进程的完成。它提供与现有的相同的功能Process.WaitForExit,唯一的区别是等待是异步的,因此它不会阻塞调用线程。
使用示例:
private async void button1_Click(object sender, EventArgs e)
{
string filePath = Path.Combine
(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
Guid.NewGuid().ToString() + ".txt"
);
File.WriteAllText(filePath, "Hello World!");
try
{
using Process process = new();
process.StartInfo.FileName = "Notepad.exe";
process.StartInfo.Arguments = filePath;
process.Start();
await process.WaitForExitAsync();
}
finally
{
File.Delete(filePath);
}
MessageBox.Show("Done!");
}
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,当用户与打开的文件交互时,UI 保持响应。WaitForExit如果使用的话,UI 线程将会被阻塞。
| 归档时间: |
|
| 查看次数: |
68949 次 |
| 最近记录: |