如何在多线程中调用winform窗体控件
时间:2022-04-23
本文章向大家介绍如何在多线程中调用winform窗体控件,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
由于 Windows 窗体控件本质上不是线程安全的。因此如果有两个或多个线程适度操作某一控件的状态(set value),则可能会迫使该控件进入一种不一致的状态。还可能出现其他与线程相关的 bug,包括争用和死锁的情况。于是在调试器中运行应用程序时,如果创建某控件的线程之外的其他线程试图调用该控件,则调试器会引发一个 InvalidOperationException
本文用一个很简单的示例来讲解这个问题(在窗体上放一个TextBox和一个Button,点击Button后,在新建的线程中设置TextBox的值)
解决办法一: 关闭该异常检测的方式来避免异常的出现
经过测试发现此种方法虽然避免了异常的抛出,但是并不能保证程序运行结果的正确性 (比如多个线程同时设置TextBox1的Text时,很难预计最终TextBox1的Text是什么)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace winformTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;//这一行是关键
}
private void button1_Click(object sender, EventArgs e)
{
SetTextBoxValue();
}
void SetTextBoxValue()
{
TextBoxSetValue tbsv = new TextBoxSetValue(this.textBox1, "Method1");
ThreadStart TS = new ThreadStart(tbsv.SetText);
Thread T = new Thread(TS);
T.Start();
}
class TextBoxSetValue
{
private TextBox _TextBox ;
private string _Value;
public TextBoxSetValue(TextBox TxtBox, String Value)
{
_TextBox = TxtBox;
_Value = Value;
}
public void SetText()
{
_TextBox.Text = _Value;
}
}
}
}
解决办法二:通过委托安全调用
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace winformTest
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
SetTextBoxValue();
}
private delegate void CallSetTextValue();
//通过委托调用
void SetTextBoxValue()
{
TextBoxSetValue tbsv = new TextBoxSetValue(this.textBox1, "Method2");
if (tbsv.TextBox.InvokeRequired)
{
CallSetTextValue call = new CallSetTextValue(tbsv.SetText);
tbsv.TextBox.Invoke(call);
}
else
{
tbsv.SetText();
}
}
class TextBoxSetValue
{
private TextBox _TextBox;
private string _Value;
public TextBoxSetValue(TextBox TxtBox, String Value)
{
_TextBox = TxtBox;
_Value = Value;
}
public void SetText()
{
_TextBox.Text = _Value;
}
public TextBox TextBox {
set { _TextBox = value; }
get { return _TextBox; }
}
}
}
}
- 算法 | 排序算法图形化比较:快速排序、插入排序、选择排序、冒泡排序
- WCF 添加 RESTful 支持,适用于 IIS、Winform、cmd 宿主
- 在CentOS 7上安装Nginx服务器
- 卷积神经网络 | 深度学习笔记1
- 【直播】我的基因组65:看看哪些基因的突变较多,哪些较少
- angular之interceptors拦截器
- js list数据 转 树状 层级 JSON,递归生成树状 层级 JSON
- jquery 图片文件转base64 显示
- AngularJS 用 $http.jsonp 跨域SyntaxError问题
- 简单的java socket 示例
- Hadoop二次开发环境构建
- Android EditText 获得输入焦点 以及requestfocus()失效的问题
- 【直播】我的基因组68:看看哪些基因的突变较多,哪些较少
- GDI+编程
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【tensorflow2.0】损失函数losses
- 如何在python文件中测试sql语句
- 用C++跟你聊聊“适配器模式”
- 【tensorflow2.0】评价指标metrics
- 数据库(二)--多对多相关操作
- 【tensorflow2.0】优化器optimizers
- 数据库(三)--多对多,一对多,一对一
- 【tensorflow2.0】回调函数callbacks
- 用C++跟你聊聊“观察者模型”
- 【tensorflow2.0】构建模型的三种方法
- django实战(一)--dango自带的分页(极简)
- 线程池 -- 动态链接库
- 【tensorflow2.0】训练模型的三种方法
- 用C++跟你聊聊“建造者模式”
- 【tensorflow2.0】使用TPU训练模型