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(或是需要改进的地方)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android开发之图片旋转功能实现方法【基于Matrix】
- Android编程简单实现拨号器功能的方法
- win10 + Ubuntu20.04 LTS双系统引导界面美化
- Android开发从相册中选取照片的示例代码
- 详解Android WebView的input上传照片的兼容问题
- Ubuntu14.04安装、配置与卸载QT5的步骤详解
- CentOS 8 安装 MariaDB的详细教程
- Android中RecyclerView拖拽、侧删功能的实现代码
- Android单个RecyclerView实现列表嵌套的效果
- Android如何禁止向EditText控件中输入内容详解
- 小程序视角下同构方案思考
- Android基于自带的DownloadManager实现下载功能示例
- Linux服务器搭建nvidia-docker环境过程详解
- Android开发中libs和jinLibs文件夹的作用详解
- Android多线程之同步锁的使用