博客
-
[C#笔记] 解决 WinForm 跨线程更新 UI 报错的问题
最近在写一个小工具的时候踩了个坑,记录一下以防下次忘记。
问题描述: 我在后台开了一个
Task去处理一些耗时的数据,处理完后想把结果显示在界面的TextBox里。结果一运行程序就直接崩了,抛出了一个经典的异常:System.InvalidOperationException: 'Cross-thread operation not valid: Control 'textBoxLog' accessed from a thread other than the thread it was created on.'也就是常说的“线程间操作无效”。因为 WinForm 的 UI 控件并不是线程安全的,子线程不能直接去动主线程创建的控件。
// 模拟后台任务 Task.Run(() => { Thread.Sleep(1000); // 假装在工作 // 直接操作 UI 控件 -> 报错! this.textBoxLog.AppendText("任务完成!"); });解决方法: 其实很简单,判断一下
InvokeRequired,然后用this.Invoke把操作封送回主线程就行了。Task.Run(() => { Thread.Sleep(1000); // 检查是否需要跨线程调用 if (this.textBoxLog.InvokeRequired) { // 使用 Invoke 委托给主线程执行 this.textBoxLog.Invoke(new Action(() => { this.textBoxLog.AppendText("任务完成!\r\n"); })); } else { this.textBoxLog.AppendText("任务完成!"); } });搞定,程序不再崩溃了。虽然 WPF 有
Dispatcher,但 WinForm 这一套Invoke还是得熟练掌握才行。
