欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程语言 > asp.net >内容正文

asp.net

Silverlight与WPF中BeginInvoke的差异

发布时间:2025/7/14 asp.net 36 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Silverlight与WPF中BeginInvoke的差异 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

Silverlight/WPF中,如果要在多线程中对界面控件值做修改,用Dispatcher对象的BeginInvoke方法无疑是最方便的办法 ,见:温故而知新:WinForm/Silverlight多线程编程中如何更新UI控件的值

但今天发现WPF中的BeginInvoke却无法自动将匿名方法/Lambda表达式转变成Delegate类型(注:对委托,匿名方法,Lambda感到陌生的朋友先阅读温故而知新:Delegate,Action,Func,匿名方法,匿名委托,事件)

silverlight中的代码片段:

private void button1_Click(object sender, RoutedEventArgs e) {Thread t = new Thread(TestMethod); t.Start();Thread t2 = new Thread(TestMethod2);t2.Start("Hello World"); }void TestMethod() {this.Dispatcher.BeginInvoke(() => { this.textBlock1.Text = DateTime.Now.ToString("HH:mm:ss"); }); }void TestMethod2(object s) {this.Dispatcher.BeginInvoke(() => { this.textBlock1.Text =s.ToString() ; }); }

WPF中如果这样用,会报如下错误: 

Cannot convert lambda expression to type 'System.Delegate' because it is not a delegate type

即:无法将lambda表达式转换为"System.Delegate",因为它不是delegate 类型


即使把Lambda表达式改成匿名方法的写法也不行:

public void TestMethod() {this.Dispatcher.BeginInvoke(delegate() { this.textBlock1.Text = DateTime.Now.ToString("HH:mm:ss fff"); }); }

仍然会报错:
Cannot convert anonymous method to type 'System.Delegate' because it is not a delegate type

即:无法将匿名方法转换为"System.Delegate",因为它不是delegate 类型


当然也可以自己定义一个Delegate类型用最传统的方法来写:

delegate void MyDelegate();delegate void MyDelegate2(object s);public void TestMethod(){MyDelegate d = new MyDelegate(UpdateText);this.Dispatcher.BeginInvoke(d);}void UpdateText(){this.textBlock1.Text = DateTime.Now.ToString("HH:mm:ss fff");}void UpdateText2(object s){this.textBlock1.Text = s.ToString();}public void TestMethod2(object s){MyDelegate2 d = new MyDelegate2(UpdateText2);this.Dispatcher.BeginInvoke(d, "Hello World");}

但是这种写法太繁琐了,还得单独把方法的定义提取出来,同时还要定义相应的委托类型,难道不能象Silverlght中那样清爽一点么?

既然出错的原因就是编译器不自动做类型转换,那我们就来强制转换吧

public void TestMethod() {this.Dispatcher.BeginInvoke((Action)delegate() { this.textBlock1.Text = DateTime.Now.ToString("HH:mm:ss fff"); }); } public void TestMethod2(object s) {this.Dispatcher.BeginInvoke((Action)(() => { this.textBlock1.Text = s.ToString(); })); }

 

这样就可以了,把匿名方法/Lambda表达式强制转换为Action,而Action实质就是委托类型,so,问题解决了!


不过仍然有点疑问:为啥编译器能自动认别Silverlight,却不认WPF呢?这算不算是编译器的BUG(或是需要改进的地方)

转载于:https://www.cnblogs.com/yjmyzz/archive/2010/03/18/1689256.html

总结

以上是生活随笔为你收集整理的Silverlight与WPF中BeginInvoke的差异的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。