多线程操作Winform控件
这是一个老问题了,对新手比较困惑,不过网上有很多讨论。.net 2.0之后,Winform控件默认不允许由非它所在的线程改变它的状态。如果你在其他的线程中改变控件的状态,则会抛出异常 Cross-thread operation not valid.窃以为,Control类对于多线程操作应该封装起来,不知道微软为何没这么做。这个问题解决也不难,Control有一个Invoke方法,它接受一个委托作为参数,它可以把委托中的代码加载到控件所在的线程中执行。Control类有个RequireInvoke属性,用来判断当前对控件的操作是否必须通过Invoke来执行,也就是,当前的代码是否和控件在同一个线程中。因此解决方案如下,假如我们有一个Form,上面有一个TextBox控件,TextBoxInformation,我们为Form添加一个方法,通过调用这个方法,其它线程也可以向这个textbox添加数据:
public void LogMessage(string message) { if (textBoxInfomation.InvokeRequired) { MethodInvoker fn = delegate { LogMessage(message); }; this.Invoke(fn); } else textBoxInfomation.Text += message + "\r\n"; }
其中,MethodInovker,是一个委托,不接受任何参数,.net 2.0 开始包括这个委托的声明。 这个方法很简单,就是判断下是否需要Invoke,如果需要,则新建一个委托,将这个方法本身传递给当前控件的线程执行。这个解决方案简单而无聊,如果有大量跨线程的方法,这样写就比较麻烦了。不过也没有太好的方法,如果你用的是.net 3.0,则可以使用extension method 来化简下,具体讨论见:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构