窗口关闭时如何正确终止任务与进程?解决频繁重开异常
问题解决方案
核心问题分析
频繁快速重开窗口时出现“任务已取消或释放”报错,主要原因是:
- 窗口关闭时未检查
CancellationTokenSource状态就直接调用Cancel()和Dispose(),触发重复操作已释放对象的异常 - 异步任务未正确响应取消信号,且
Start()方法存在语法错误 - 进程终止逻辑顺序不合理,未判断进程是否仍在运行
修正方案
1. 优化CancellationTokenSource生命周期管理
窗口关闭时先检查CancellationTokenSource状态,避免重复执行取消/释放操作;调整操作顺序,先取消任务再释放资源。
2. 实现异步任务的取消响应
在任务执行过程中定期检查取消令牌,确保任务能及时终止;修正Start()方法的语法错误,正确传递取消令牌。
3. 规范进程终止逻辑
先判断进程是否处于运行状态,再调用Kill(),并等待进程完全终止后再释放资源,避免操作已结束的进程。
修改后的代码
class MyAdditionalWindowClass { private CancellationTokenSource _cts; private Process _process; public MyAdditionalWindowClass() { _cts = new CancellationTokenSource(); Start(); this.Closed += OnWindowClosed; } private async void Start() { try { await Task.Run(() => ToDoSomething(_cts.Token), _cts.Token); // 后续代码需先检查取消状态 if (_cts.Token.IsCancellationRequested) return; // 其他业务逻辑 } catch (OperationCanceledException) { // 任务取消的常规处理,无需抛出异常 } } private void ToDoSomething(CancellationToken token) { // 创建进程前先检查取消信号 token.ThrowIfCancellationRequested(); _process = new Process(); // 配置进程启动参数 _process.StartInfo = new ProcessStartInfo("你的可执行文件路径") { UseShellExecute = false, CreateNoWindow = true }; _process.Start(); // 循环检查取消信号,同时等待进程结束 while (!_process.HasExited) { token.ThrowIfCancellationRequested(); Thread.Sleep(100); // 短间隔轮询,减少资源占用 } } private void OnWindowClosed(object sender, EventArgs e) { // 终止并清理进程 if (_process != null && !_process.HasExited) { try { _process.Kill(); _process.WaitForExit(1000); // 等待1秒确保进程终止 } catch (InvalidOperationException) { // 进程已终止的异常处理 } finally { _process.Close(); _process.Dispose(); _process = null; } } // 处理CancellationTokenSource if (_cts != null) { try { if (!_cts.IsCancellationRequested) { _cts.Cancel(); } } catch (ObjectDisposedException) { // 已释放的情况无需处理 } finally { _cts.Dispose(); _cts = null; } } } }
关键改动说明
- 将匿名事件处理改为命名方法
OnWindowClosed,提升代码可读性 - 在
ToDoSomething()中添加token.ThrowIfCancellationRequested(),确保任务及时响应取消 - 进程终止时增加状态检查和等待逻辑,避免操作已终止的进程
- 对
CancellationTokenSource的操作添加异常捕获,处理重复释放/取消的场景 - 修正
Task.Run的语法错误,正确传递取消令牌
内容的提问来源于stack exchange,提问作者Cobret
相关产品推荐
相关产品推荐

