无法将 匿名方法 转换为类型“System.Delegate”,因为它不是委托类型

简介:

http://blog.csdn.net/xiaochongchong1248/archive/2009/11/20/4841193.aspx?1271573283

编程环境要求: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 " ));


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


本文转自火地晋博客园博客,原文链接:http://www.cnblogs.com/yelaiju/archive/2010/09/16/1827691.html,如需转载请自行联系原作者

目录
相关文章
|
编解码 芯片
STM32--TIM定时器(2)
STM32--TIM定时器(2)
1098 0
你的应用进入了中断状态,但无任何代码显示,因为所有线程之前都在执行外部代码
你的应用进入了中断状态,但无任何代码显示,因为所有线程之前都在执行外部代码
3403 0
你的应用进入了中断状态,但无任何代码显示,因为所有线程之前都在执行外部代码
|
6月前
|
存储 弹性计算 关系型数据库
2026年阿里云服务器免费试用指南:新用户免费优惠、续费政策与深度解析
2026年,阿里云延续免费试用政策并推出创新优惠。其免费试用产品覆盖计算、存储等多个领域,个人和企业新用户可享不同配置与试用时长,权益构成透明且试用灵活。试用后仍可享受新用户优惠价格,新用户可通过实名认证等条件享受首购折扣、专享套餐等优惠。续费时有折扣政策,但需注意续费时间等事项。
|
人工智能 运维 自然语言处理
电力+AI,「国网云智」重构电网运维的"超级大脑"
在深夜,当城市楼宇渐入梦乡时,在国网信通公司云运营中心还有一批运维工程师默默守护着大家微弱的灯光、此起彼伏的沟通声、咔咔的键盘敲击声响彻着每个工位。 当某系统的异常警报亮起时,工程师迅速利用「国网云智」定位问题,屏幕上即刻弹出详尽的排查方案及解决方案;而另一侧的监控员框选闪烁的告警区域,系统已自动锁定故障点,并在生成检修方案上标注了对应的工具清单和操作优先级。
1378 0
|
机器学习/深度学习 文字识别 算法
[Halcon&图像] 缺陷检测的一些思路、常规检测算法
[Halcon&图像] 缺陷检测的一些思路、常规检测算法
8828 2
|
数据库
SqlServer如何给表添加新的字段以及字段注释
SqlServer如何给表添加新的字段以及字段注释
846 1
|
JavaScript 前端开发
Vue3动态面包屑的实现
Vue3动态面包屑的实现
844 0
|
存储 安全 内存技术
地址映射
地址映射
1081 0
|
自然语言处理 资源调度 前端开发
前端大模型入门(四):不同文本分割器对比和效果展示-教你如何根据场景选择合适的长文本分割方式
本文详细介绍了五种Langchain文本分割器:`CharacterTextSplitter`、`RecursiveCharacterTextSplitter`、`TokenTextSplitter`、`MarkdownTextSplitter` 和 `LatexTextSplitter`,从原理、优缺点及适用场景等方面进行了对比分析,旨在帮助开发者选择最适合当前需求的文本分割工具,提高大模型应用的处理效率和效果。
3291 1