当前位置:网站首页>解决C#跨线程调用窗体控件的问题
解决C#跨线程调用窗体控件的问题
2022-07-26 08:30:00 【luobeihai】
遇到问题
在用C#写一个窗体应用程序的时候,调试的时候突然报错,说我的线程操作无效,不是从创建控件的线程去访问控件。
网上查了下出现这个问题的原因是:
C#只有主线程才能访问控件。
从 .NET Framework 2.0 类库开始,.net框架就对于 winform 中采用多线程调用窗体控件进行了安全性检测,就是说我从另外一个不是主线程的线程去调用窗体控件的话,就会出现异常。
解决方法
解决跨线程间调用的方法有很多,这里介绍两种。
1. 直接关闭跨线程访问控件的安全检查
关闭安全检查,我们只要在窗体函数中加入下面一句代码即可:
public Form1()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false; // 这句代码就是关闭了安全检查
}
这种方法是最简单的,直接关闭了跨线程间访问控件的安全检查,那么就可以允许你在其他各个子线程乱改控件的属性,这样的访问是不可控的,所以这种方法不推荐使用。
2. 通过委托调用
C#的委托调用,类似C语言中的函数指针作为函数参数一样。
C#提供了delegate和invoke来从其他线程中调用控件。
简化的使用方法如下,就是直接在需要跨线程访问控件的那部分代码,写在 delegate 括起来的里面即可。
this.Invoke(new EventHandler (delegate
{
// 这里面就是访问控件相关的代码了
label1.Text = "hello";
}));
比如,我前面一开始遇到的,就是我在一个网络数据接收的线程,把接收的数据写到接收的文本框里面,不加 Invoke 的话就会报错,加了就不会,如下代码:
private void ReceiveCallback(IAsyncResult AR)
{
// Check how much bytes are recieved and call EndRecieve to finalize handshake
this.Invoke(new EventHandler(delegate
{
try
{
int recieved = tcpClient.EndReceive(AR);
if (recieved <= 0)
return;
string message = Encoding.GetEncoding("GBK").GetString(recieveBuffer, 0, recieved); // 只将接收到的数据进行转化
// 这里就是跨线程访问了tbRecv文本框控件,这里实际上就是想把接收到的数据添加到文本框上显示出来
tbRecv.AppendText($"[{
DateTime.Now.ToString("yyy-MM-dd HH.mm.ss.fff")}] {
message}\r\n");
// Start receiving again
tcpClient.BeginReceive(recieveBuffer, 0, recieveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);
}
catch (SocketException ex)
{
MessageBox.Show(ex.ToString());
}
}));
}
边栏推荐
- Leetcode and query question summary
- Kotlin中room数据库的使用
- 【时间复杂度空间复杂度】
- Excel find duplicate lines
- Alphabetic string
- shell编程
- Error handling response: Error: Syntax error, unrecognized expression: .c-container /deep/ .c-contai
- Apple's tough new rule: third-party payment also requires a percentage, and developers lose a lot!
- vscode 实用快捷键
- Nodejs2day(nodejs的模块化,npm下载包,模块加载机制)
猜你喜欢
![[C language] programmer's basic skill method -](/img/0e/e9111d4b341cc42aa4382b5fbd0001.png)
[C language] programmer's basic skill method - "creation and destruction of function stack frames"

【C语言】程序员筑基功法——《函数栈帧的创建与销毁》

Lesson 3: gcc compiler

B title: razlika priority queue approach

内存管理-动态分区分配方式模拟

Super nice navigation page (static page)

Winter vacation homework & Stamp cutting

Kotlin operator

Spark persistence strategy_ Cache optimization

Add in the registry right click to open in vscode
随机推荐
vscode国内的镜像服务器加速
[endnote] detailed explanation of document template layout syntax
Leetcode and query question summary
Kotlin program control
Spark scheduling analysis
Flutter compilation fails
Seq2seq and attention model learning notes
Using the primitive root of module m to judge and solve
Excel delete blank lines
shell编程
Write common API tools swagger and redoc
2022-024arts: Longest valid bracket
Mysql/mariadb (Galera multi master mode) cluster construction
日常一记(11)--word公式输入任意矩阵
2022/7/18 exam summary
Memory management based on C language - Simulation of dynamic partition allocation
vim跨行匹配搜索
KV database based on raft consensus protocol
[abstract base class inheritance, DOM, event - learning summary]
Kotlin data type