C#程序特定代码段运行时关闭窗口触发RichTextBox已释放对象异常求助
问题原因分析
点击窗口关闭按钮时,窗体开始释放内部控件(包括tbDisplayText这个RichTextBox),但你的异步循环仍在执行——await Task.Delay(speed)之后,代码会尝试访问已经被Dispose的tbDisplayText,这就触发了ObjectDisposedException。其他场景下关闭窗口时没有这个循环在运行,所以不会报错。
解决方法
以下是几种直接可行的修复方案:
方案1:添加关闭标志位检查
- 在窗体类中定义私有字段:
private bool _isFormClosing;
- 重写窗体的
OnFormClosing方法:
protected override void OnFormClosing(FormClosingEventArgs e) { _isFormClosing = true; base.OnFormClosing(e); }
- 修改循环代码,每次操作控件前检查标志位:
while (firstColorChange < lines.Length + numTextLength.Value) { if (_isFormClosing) break; if (firstColorChange < lines.Length) { if (_isFormClosing) break; tbDisplayText.Select(firstColorChange, 1); tbDisplayText.SelectionColor = Color.Red; firstColorChange++; } if (firstColorChange > numTextLength.Value) { if (_isFormClosing) break; tbDisplayText.Select(secondColorChange, 1); tbDisplayText.SelectionColor = Color.White; secondColorChange++; } await Task.Delay(speed); if (_isFormClosing) break; if(secondColorChange == lines.Length) { if (!_isFormClosing) tbDisplayText.Clear(); break; } }
方案2:直接检查控件的IsDisposed属性
每次操作tbDisplayText前,判断它是否已被释放:
while (firstColorChange < lines.Length + numTextLength.Value) { if (tbDisplayText.IsDisposed) break; if (firstColorChange < lines.Length) { if (tbDisplayText.IsDisposed) break; tbDisplayText.Select(firstColorChange, 1); tbDisplayText.SelectionColor = Color.Red; firstColorChange++; } if (firstColorChange > numTextLength.Value) { if (tbDisplayText.IsDisposed) break; tbDisplayText.Select(secondColorChange, 1); tbDisplayText.SelectionColor = Color.White; secondColorChange++; } await Task.Delay(speed); if (tbDisplayText.IsDisposed) break; if(secondColorChange == lines.Length) { if (!tbDisplayText.IsDisposed) tbDisplayText.Clear(); break; } }
方案3:使用CancellationToken(规范的异步取消方式)
- 在窗体类中定义CancellationTokenSource:
private CancellationTokenSource _cts;
- 启动循环前初始化令牌:
_cts = new CancellationTokenSource(); // 调用循环方法时传入_cts.Token
- 修改循环方法,接收CancellationToken:
async Task UpdateTextColors(CancellationToken token) { while (firstColorChange < lines.Length + numTextLength.Value && !token.IsCancellationRequested) { if (firstColorChange < lines.Length && !token.IsCancellationRequested) { tbDisplayText.Select(firstColorChange, 1); tbDisplayText.SelectionColor = Color.Red; firstColorChange++; } if (firstColorChange > numTextLength.Value && !token.IsCancellationRequested) { tbDisplayText.Select(secondColorChange, 1); tbDisplayText.SelectionColor = Color.White; secondColorChange++; } try { await Task.Delay(speed, token); } catch (OperationCanceledException) { break; } if(token.IsCancellationRequested) break; if(secondColorChange == lines.Length) { tbDisplayText.Clear(); break; } } }
- 在FormClosing事件中取消令牌:
protected override void OnFormClosing(FormClosingEventArgs e) { _cts?.Cancel(); _cts?.Dispose(); base.OnFormClosing(e); }
内容的提问来源于stack exchange,提问作者Leon
相关产品推荐
相关产品推荐

