浅谈Silverlight 跨线程的使用详解
发布时间:2021-10-16 01:23:05
新建SL4 应用程序,在MainPage下添加代码:
<Button x:Name="btnThread1" Click="btnThread1_Click">Thread1</Button>
后台代码为:
private void btnThread1_Click(object sender, RoutedEventArgs e)
{
new Thread(() =>
{
MessageBox.Show("Hello World");
}).Start();
}
如果你运行程序,点击按钮,会得到下面的异常。
这个问题的原因很简单:一个线程尝试调用另一个线程的方法 解决这个异常的方式很简单,
1:使用DependencyObject.Dispatcher.BeginInvoke 方法:
private void btnThread1_Click(object sender, RoutedEventArgs e)
{
new Thread(() =>
{
this.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("Hello World");
});
}).Start();
}
2:使用SynchronizationContext 对象
private void btnThread1_Click(object sender, RoutedEventArgs e)
{
SynchronizationContext context = SynchronizationContext.Current;
new Thread(() =>
{
context.Post((state) =>
{
MessageBox.Show("Hello World");
}, null);
}).Start();
}
但是这两者都有一个缺陷,假设有多个线程,例如多线程的多线程:
private void btnThread1_Click(object sender, RoutedEventArgs e)
{
new Thread(() =>
{
SynchronizationContext context = SynchronizationContext.Current;
new Thread(() =>
{
context.Post((state) =>
{
MessageBox.Show("Hello World");
}, null);
}).Start();
}).Start();
}
虽然这里保存了context,但是因为context并不是UI线程的SynchronizationContext,所以还是会跑出异常。
所以提出了第三种方案:
1:新建静态类UISynchronizationContext,代码如下:
/// <summary>
/// UI线程的SynchronizationContext
/// </summary>
public static class UISynchronizationContext
{
public static SynchronizationContext Context { get; set; }
}
修改App.Xaml.cs 代码的构造函数,在构造App的时候设置
UISynchronizationContext.Context = SynchronizationContext.Current;
public App()
{
this.Startup += this.Application_Startup;
this.Exit += this.Application_Exit;
this.UnhandledException += this.Application_UnhandledException;
//保存UI线程同步上小文
UISynchronizationContext.Context = SynchronizationContext.Current;
InitializeComponent();
}
使用的时候只需要:
private void btnThread1_Click(object sender, RoutedEventArgs e)
{
new Thread(() =>
{
new Thread(() =>
{
UISynchronizationContext.Context.Post((state) =>
{
MessageBox.Show("Hello World");
}, null);
}).Start();
}).Start();
}
其实Silverlight 已经提供了相似功能的类了,它就是
System.Windows.Deployment
你完全可以将上面的代码修改为:
new Thread(() =>
{
new Thread(() =>
{
//UISynchronizationContext.Context.Post((state) =>
// {
// MessageBox.Show("Hello World");
// }, null);
System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("Hello World");
});
}).Start();
}).Start();


猜你喜欢
- 项目介绍java 开发中,参数校验是非常常见的需求。但是 hibernate-validator 在使用过程中,依然会存在一些问题。vali
- mysql插件实现原理官网的关键信息参考文档https://mybatis.org/mybatis-3/zh/configuration.h
- Rsa加密RSA是目前最有影响力的公钥加密算法,RSA也是第一个既能用于数据加密也能用于数字签名的算法。该算法基于一个十分简单的数论事实:将
- 1.为什么要用thrift js C#? 1.1 首先,js 通过 thrift 访问C#,实际上是一种
- 数据存储与访问常用方式:文件SharedPreferences(偏好参数设置)SQLite数据库内容提供者(Content provider
- 以String转Date为例:定义转换器:import java.text.ParseException;import java.util.
- 本文实例为大家分享了android自定义滚动上下回弹scollView的具体代码,供大家参考,具体内容如下这是一个自定义view,在xml布
- 最近项目中用到了Elasticsearch5.4(ES)是比较新的一个版本,使用的过程中出现了很多的问题,很是头疼,但是问题最终还是解决掉了
- 本文实例为大家分享了Java Socket聊天室功能的具体代码,供大家参考,具体内容如下Client.javaimport java.io.
- Android日期选择控件效果如下:调用的代码:@OnClick(R.id.btn0) public void btn0() { final
- 如下所示:from jpype import *jvmPath = getDefaultJVMPath()jars = ["./F
- 责任链模式责任链模式的定义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系, 将这个对象连成一条链,并沿着这条链传递
- Radiobutton是一种单选按钮,是由于RadioGroup管理下的一组按钮,所以一旦其中的一个button选中,再点击,就不能取消,想
- 本文实例为大家分享了Java实现简单邮件发送的具体代码,供大家参考,具体内容如下需要的jar包:activation-1.1.1.jarma
- 使用DOM4J方式生成XML文件的步骤如下:引入JAR包通过DocumentHelper类的createDocument()创建Docume
- 对不起大家,昨天文章里的告别说早了,这个系列还不能就这么结束。我们前面的文章中讲解过RabbitMQ的用法,所谓MQ就是一种发布订阅模式的消
- 简述mysq5.7之后新增了json类型,但是在使用的过程中,Json数组中的值小于Integer.MAX_VALUE,则反序列化时会转成L
- spring中实例化bean无效在做Struts2和Spring整合时遇到Spring实例化无效的情况,Action中代码如下public
- 前言最近在维护一个运营端的系统,和前端联调的过程中,经常需要排查一些交互上的问题,每次都得看前端代码的传参和后端代码的出参,于是打算给HTT
- 需要添加引用,System.Configuration;写系统配置文件: Configuration cfa =