winform 跨线程访问问题
一、问题描述
进行winform 开发我们在进行数据交换时避免不了使用多线程或异步方法,这样操作也将避免不了跨线程对控件进行操作(赋值、修改属性)。
下面通过一个测试说明一下问题

点击一个按钮异步对textbox进行赋值
运行测试结果

private void button1_Click(object sender, EventArgs e)
{
Action<string> action = new Action<string>((str) =>
{
// 解决跨线程赋值
this.textBox1.Text = str;
});
action.BeginInvoke("Test", null, null);
}
产生错误的原因:textBox1是由主线程创建的,异步方法(或子线程)是另外创建的一个线程,在.NET上执行的是托管代码,C#强制要求这些代码必须是线程安全的,即不允许跨线程访问Windows窗体的控件。
二、解决方法
1.在窗体的加载事件中,将C#内置控件(Control)类的CheckForIllegalCrossThreadCalls属性设置为false,屏蔽掉C#编译器对跨线程调用的检查。
//取消跨线程的访问
Control.CheckForIllegalCrossThreadCalls = false;
使用上述的方法虽然可以保证程序正常运行并实现应用的功能,但是在实际的软件开发中,做如此设置是不安全的(不符合.NET的安全规范),在产品软件的开发中,此类情况是不允许的。如果要在遵守.NET安全标准的前提下,实现从一个线程成功地访问另一个线程创建的空间,要使用C#的方法回调机制。
2.使用回调函数 ( 委托的应用 )
(1) 定义声明回调
(2) 初始化回调
(3) 触发动作
/// <summary>
/// 定义委托
/// </summary>
/// <param name="str"></param>
private delegate void SetValueDelegate(string str); /// <summary>
/// 声明委托
/// </summary>
SetValueDelegate test; /// <summary>
/// 回调方法
/// </summary>
/// <param name="str"></param>
private void SetTbValue(string str)
{
this.textBox1.Text = str;
} private void button1_Click(object sender, EventArgs e)
{
// 实例化委托
test = new SetValueDelegate(SetTbValue); Action<string> action = new Action<string>((str) =>
{
// 解决跨线程赋值
this.textBox1.Invoke(test, str);
}); action.BeginInvoke("Test", null, null);
}
我个人比较使用喜欢使用事件解决(原理同委托一样),但省掉不少代码
private void button1_Click(object sender, EventArgs e)
{
Action<string> action = new Action<string>((str) =>
{
// 解决跨线程赋值
this.textBox1.Invoke(
new Action<string>((param) =>
{
this.textBox1.Text = param;
}
), str);
}); action.BeginInvoke("Test", null, null);
}
winform 跨线程访问问题的更多相关文章
- winform跨线程访问控件
首先说下,.net 2.0以后加强了安全机制,不允许在winform中直接跨线程访问控件的属性.所以除了控件所在的线程外的线程调用会抛异常 (Cross-thread operation not va ...
- WPF / Win Form:多线程去修改或访问UI线程数据的方法( winform 跨线程访问UI控件 )
WPF:谈谈各种多线程去修改或访问UI线程数据的方法http://www.cnblogs.com/mgen/archive/2012/03/10/2389509.html 子线程非法访问UI线程的数据 ...
- C# WinForm 跨线程访问控件
问题出现: 在WinForm 处理多线程访问主线程的控件时候,就会出现如图所示的错误对话框: 解决方案: 方案一:去掉线程访问主线程UI控件的安全检查,使用: Control.CheckFor ...
- C#之Winform跨线程访问控件
C#中禁止跨线程直接访问控件,InvokeRequired是为了解决这个问题而产生的,当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它.此时它将会在内部调用ne ...
- C# WinForm 跨线程访问控件(实用简洁写法)
C# WinForm 跨线程访问控件(实用简洁写法) 1.<C# WinForm 跨线程访问控件(实用简洁写法)> 2.<基于.NET环境,C#语言 实现 TCP NAT ...
- Winform 让跨线程访问变得更简单
Winform 让跨线程访问变得更简单 前言 由于多线程可能导致对控件访问的不一致,导致出现问题.C#中默认是要线程安全的,即在访问控件时需要首先判断是否跨线程,如果是跨线程的直接访问,在运行时会抛出 ...
- 实现Winform 跨线程安全访问UI控件
在多线程操作WinForm窗体上的控件时,出现“线程间操作无效:从不是创建控件XXXX的线程访问它”,那是因为默认情况下,在Windows应用程序中,.NET Framework不允许在一个线程中直接 ...
- 如何跨线程访问Winform中的UI元素
如何跨线程访问Winform中的UI元素 假如制作一个Socket聊天应用程序,很可能会用到多线程: 例如为Receive方法开辟单独一个线程,例如为Receive方法开辟单独一个线程(后台运行的线程 ...
- Winform之跨线程访问控件(在进度条上显示字体)
此文章对于遇到必须使用线程但是没有办法在线程内操作控件的问题的处理 有很好的解决方案(个人认为的.有更好的方案欢迎交流.) 在做跨线程访问之前我们先了解下我们所做的需要达到的效果: 这个是批量的将x ...
随机推荐
- 文本分布式表示(二):用tensorflow和word2vec训练词向量
看了几天word2vec的理论,终于是懂了一些.理论部分我推荐以下几篇教程,有博客也有视频: 1.<word2vec中的数学原理>:http://www.cnblogs.com/pegho ...
- 搭建SpringCloud-Eureka 注册中心以及服务提供与调用
纸上得来终觉浅,绝知此事要躬行啊~果然看着很easy,自己搞起来就是各种坑~各位看官,容我慢慢道来~ 关于springcloud是什么我就不废话了~ Eureka Eureka(原来以为是缩写,原来 ...
- git解析日志常用命令
git diff --name-only ORIG_HEAD 获取变更列表 git log -p 查看每个提交引入的实际更改. git log --oneline --decorate 查看日志列表 ...
- python中字符串拆分与合并——split()、join()、strip()和replace()
Python3 split()方法 描述split()通过指定分隔符对字符串进行切片,如果参数num 有指定值,则仅分隔 num 个子字符串 语法split()方法语法: str.split(str= ...
- Vue 进阶之路(六)
上篇文章我们分析了一下 vue 中的条件渲染,本篇我们说一下 vue 中的列表渲染和 set 方法. <!DOCTYPE html> <html lang="en" ...
- 生产环境一键创建kafka集群
前段时间公司的一个kafka集群出现了故障,由于之前准备不足,当时处理的比较慌乱.如:由于kafka的集群里topic数量较多,并且每个topic的分区数量和副本数量都不是一样的,如果按部就班的一个一 ...
- 浅谈unity中gamma空间和线性空间
转载请标明出处:http://www.cnblogs.com/zblade/ 一.概述 很久没有写文章了,今天写一篇对gamma空间和线性空间的个人理解总结,在查阅和学习了各个资料后,算是一个个人笔记 ...
- 【技术讨论】RF环境搭建手册
(原创文章,转载请注明出处.) 简要整理下环境搭建的步骤,以便快速.准确的搭建测试环境. 一.环境搭建 一.Python 2.7 1. 不要用Python3.6,很多库3.6中还没有,wxPython ...
- 超好用的C#控制台应用模板
本文是Wei的公众号投稿文章: 默认模板之缺 在工作学习中,我们经常需要创建一些简单的控制台应用(Console App)去验证某个想法,或者作为小工具交付给其他同事. 通常我们的选择是 Visual ...
- Java遍历Map的4种方式
public static void main(String[] args) { // 循环遍历Map的4中方法 Map<Integer, Integer> map = new HashM ...