心得 如何优雅地跨线程修改主线程窗口控件

编程环境要求:VS2008/FX2.0

众所周知,从VS2005/FX2.0起,在多线程环境下是不允许跨线程修改主线程上窗口控件的。

例如:

 

private void button1_Click(object sender, EventArgs e)
{
    Thread t 
= new Thread(new ThreadStart(CrossThreadCall));
    t.Start();
}
public void CrossThreadCall()
{
    Text 
= "test";
}


将直接导致异常:
未处理 System.InvalidOperationException
  Message="线程间操作无效: 从不是创建控件“Form1”的线程访问它。"
  Source="System.Windows.Forms"
  StackTrace:
       在 System.Windows.Forms.Control.get_Handle()
       在 System.Windows.Forms.Control.set_WindowText(String value)
       在 System.Windows.Forms.Form.set_WindowText(String value)
       在 System.Windows.Forms.Control.set_Text(String value)
       在 System.Windows.Forms.Form.set_Text(String value)
       在 delegate_test1.Form1.CrossThreadCall() 位置 f:\app\delegate_test1\delegate_test1\Form1.cs:行号 26
       在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       在 System.Threading.ThreadHelper.ThreadStart()

通用的解决方法是使用Control.Invoke方法来调用一个Delegate,从而安全地跨线程调用。

例如:

 

public void CrossThreadCall()
{
    Invoke(
new void_d(CrossThreadCall_Local));
}
void CrossThreadCall_Local()
{
    Text 
= "test";
}
public delegate void void_d();


但是这样的缺点是要不得不为每个调用编写一个Invoke跳板,还要额外声明一个委托类型,实在不怎么优雅。

于是我们想到用匿名函数来写。我的第一反应是:

 

Invoke(delegate { Text = "test"; });


可惜不行。编译压根就没通过,写着:
无法将 匿名方法 转换为类型“System.Delegate”,因为它不是委托类型

无语,delegate竟然不是委托类型?

等我把Google翻了一遍后,找到了答案。

The problem the user is seeing is that the Thread ctor accepts a specific delegate -- the ThreadStart delegate.  The C# compiler will check and make sure your anonymous method matches the signature of the ThreadStart delegate and, if so, produces the proper code under-the-covers to create the ThreadStart delegate for you.

But Control.Invoke is typed as accepting a "Delegate".  This means it can accept any delegate-derived type.  The example above shows an anonymous method that has a void return type and takes no parameters.  It's possible to have a number of delegate-derived types that match that signature (such as MethodInvoker and ThreadStart -- just as an example).  Which specific delegate should the C# compiler use?  There's no way for it to infer the exact delegate type so the compiler complains with an error.

也就是说,对于Thread.ctor()来说,由于接受的是一个ThreadStart委托,编译器便可以将匿名函数与ThreadStart委托类型匹配,最后能够正确编译。
而对于Control.Invoke()来说,任何的代理类型都是可接受的,也就是说ThreadStart和MethodInvoker都是可以接受的类型。这样编译器反而不知道应该用哪个代理去匹配匿名函数了,导致了编译错误的发生。

知道了原因,问题就很容易解决了。我们只需要加上MethodInvoker这个wrapper就能使用匿名函数了。

Invoke(new MethodInvoker(delegate { Text = "test"; }));


或者更简单地,用Lambda表达式来解决问题:

Invoke(new MethodInvoker(() => Text = "test"));

希望本文能够帮助有同样困惑的朋友。

转载于:https://www.cnblogs.com/msg7086/articles/1266096.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/381587.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

刷recovery工具apk_红米note4X刷lineage,不喜欢miui10广告臃肿的可以试一试

经常在miui和各个类原生安卓系统间换来换去,不过miui10现在是越来越垃圾了,广告、耗电、臃肿,我现在已经逐步抛弃miui了!小白可以看我的帖子做个参考,刷机其实是特别简单的是,只要一步步来,总会…

关于弹框

confirm("提示字串") 为一个询问视窗,选确定传回true 否则传回false <a href"网页参数" onClick"return confirm(确认要删除吗?)"> 如果按确定就回车true ,onClick事件成立,就传送参数到删除网页进行删除 否则就没有任何动作 转载于:http…

poj 3710——Christmas Game

题意&#xff1a; 给定多个无向有环图&#xff0c;两个人在树上博弈&#xff0c;问博弈结果。 思路&#xff1a; 如果没有环&#xff0c;则是一个标准的树上博弈&#xff0c;那么满足 1. 叶子节点的sg为0 2. 中间节点的sg为所有儿子节点的sg1的异或和 存在环的话&#xf…

干涉测量技术的应用_技术分享 | 石化行业测量仪表应用在线答疑

众所周知&#xff0c;在化工和石化这类流程行业当中&#xff0c;稳定性和持续性是至关重要的生产“命脉”&#xff0c;对于生产过程中使用的测量仪表有着极其严格的要求。不仅所有测量仪表都必须满足严苛的国际标准&#xff0c;如PED和ATEX&#xff0c;压力、温度及液位等电子和…

WCF学习(五)数据契约之已知类型

准备技术&#xff1a; 1.C#基础知识 2.了解WCF基础知识 在正常的c#开发中我们是允许用子类去替换基类的&#xff0c;这也是所谓的替换原则。但是我们在WCF中确不能用数据契约的子类来替换父类的&#xff0c;因为这中间存在一个序列化的问题。举个例子&#xff1a; 我们有数据契…

hdu 3094——A tree game

题意&#xff1a; 一颗树&#xff0c;然后两个操作&#xff0c;一是删除一条边&#xff0c;二是移除不与根相连的部分。 思路&#xff1a; 树上博弈的基础题目。 code&#xff1a; #include <bits/stdc.h> using namespace std;const int N1e55; std::vector<int…

win10必须禁用的服务_7寸屏的迷你电脑,就算是8GB运行内存,也必须关闭的系统选项...

现在的电脑&#xff0c;基本上都安装的是Win10系统了&#xff0c;7寸屏的迷你笔记本电脑GPD Pocket 2琥珀黑版也不例外&#xff0c;GPD Pocket 2采用的是赛扬双核3965y处理器&#xff0c;8G运行内存&#xff0c;处理办公应用可以说是游刃有余&#xff0c;但是Win10系统有一些选…

hdu 3590——PP and QQ

题意&#xff1a; 有多颗树&#xff0c;然后树上删边游戏&#xff0c;最后一个删的人输。 思路&#xff1a; 其实就是树上删边游戏和anti-sg结合嘛。 对于树上删边&#xff1a; 1. 叶子节点的sg为0 2. 中间节点的sg为所有儿子节点的sg1的异或和 对于anti-sg&#xff1a;…

iTunes只能装C盘吗_电脑技巧分享:安装win10系统时系统盘C盘分区多大空间适合?...

我们在使用电脑时为了对电脑文件的方便管理&#xff0c;往往会对电脑进行分区&#xff0c;比如C&#xff0c;D&#xff0c;E&#xff0c;F盘等&#xff0c;其中C盘默认为系统盘&#xff0c;用于存储操作系统的重要文件&#xff0c;而C盘的分区大小也是许多朋友在安装操作系统时…

上海梵科信息科技有限公司

1. a5, b(a)(a)(a), printf("%d",b); 答案&#xff1a;19 2. 表students&#xff0c;有id, classid, name, score。 班级为4的所有学生&#xff1f; 答案&#xff1a;select * from students where classid4 每个班级的学生总数&#xff1f; 答案&#xff1a;select …

博弈论探讨及题目总结

转载自爱神博客:http://blog.csdn.net/acm_cxlove/article/details/7854526 首先当然要献上一些非常好的学习资料&#xff1a; 基础博弈的小结&#xff1a;http://blog.csdn.net/acm_cxlove/article/details/7854530 经典翻硬币游戏小结&#xff1a;http://blog.csdn.net/acm…

python36安装numpy_安装numpy

为了运行机器学习书上的实例&#xff0c;安装numpy.照着网上教程安装的&#xff0c;网上教程 1&#xff09;下载numpy包 自己的是python3.5, 64位操作系统&#xff0c;所以选择numpy-1.11.2mkl-cp35-cp35m-win-amd64.whl 2&#xff09;安装numpy 将下载的包拷贝到python安装目录…

WCF Testing Tool(转)

原文:http://jayce.clearviewtickets.info/wcftestingtool.html best video: wcf testing tool IIS7 Admin Pack Offers Built In Performance Analysis Reports Are you web developer building high traffic web site? Are you performance engineer that lives and breath…

hdu 5299——Circles Game

题意: 给定n个嵌套的圆&#xff0c;每次可以删除圆以及该圆包含的所有圆&#xff0c;不能删除者输。 思路&#xff1a; 把每个圆看成一个点&#xff0c;把圆的包含关系看成一条单向边&#xff0c;那么就化成了一棵树。 然后就是裸的树上删边游戏模型了。 对于树上删边游戏…

python制作简单动画_如何使用python制作简单的动画?

Python真的是无穷的好用&#xff0c;涉及内容非常广泛&#xff0c;比如接下来给大家介绍的制作动画&#xff0c;就可以利用python实现&#xff0c;相信小伙伴们听到这些内容肯定是非常感兴趣的&#xff0c;至于怎么去实现&#xff1f;大家想不想了解呢&#xff1f;下面小编就给…

asp.net 时间显示格式

asp.net里获取当前时间,并输出需要格式2007年12月08日 星期六 23:13;asp.net里获取当前时间&#xff0c;并字符串格式化转换2007-12-03 00:051.string strTime DateTime.Now.ToLongTimeString(); --------------------------------------------------------------------------…

clickhouse语句_篇四|ClickHouse的可视化界面与集群状态监控

介绍 tabix支持通过浏览器直接连接 ClickHouse&#xff0c;不需要安装其他软件&#xff0c;就可以访问ClickHouse&#xff0c;具有以下特点&#xff1a;⾼亮语法的编辑器。⾃动命令补全。查询命令执⾏的图形分析⼯具。配⾊⽅案选项。除此之外&#xff0c;还可以使用DBeaver连接…

python集合应用场景_python 集合的应用

应用场景 磁盘资产采集信息&#xff0c;与数据库中的磁盘信息需要进行对比&#xff0c;再资产入库&#xff0c;对于采集的多余的插巢属于新增的磁盘&#xff0c;对于相同的插巢可能是磁盘容量变更&#xff0c;对于数据库中有但是采集信息中没有的插巢是资产中删除的磁盘。 原始…

Codeforces Round #381 (Div. 2) Codeforce_740

A. Alyona and copybooks 水题&#xff0c;让求满足条件的最小花费&#xff0c;注意组合可能是多个即可。 #include <bits/stdc.h> using namespace std;typedef long long ll;int main(int argc, char const *argv[]) {ll n,a,b,c;cin>>n>>a>>b>…

mootools框架【十】-mootools深层探讨

mootools【十】- window的扩展及多彩世界 一. Mootools 框架对 Window的扩展: 浏览器的window对象本身就提供了我们很多的对浏览器本身属性的获取或设置的方法&#xff0c;但是我们也知道&#xff0c;由于各大浏览器之间对标准的实现不统一&#xff0c;导致很多方法功能上有所…