浅谈Silverlight 跨线程的使用详解
新建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();
相关文章
- 这篇文章主要介绍了WPF/Silverlight实现图片局部放大的方法,结合实例形式分析了WPF/Silverlight针对图片属性操作相关实现技巧,需要的朋友可以参考下...2020-06-25
- 本篇文章是对Silverlight跨线程的使用进行了详细的分析介绍,需要的朋友参考下...2020-06-25
- 这篇文章主要介绍了C#中跨线程访问控件问题解决方案,有需要的朋友可以参考一下...2020-06-25
- 这篇文章主要介绍了silverlight实现图片局部放大效果的方法,结合实例形式分析了silverlight针对图片属性的相关操作技巧,需要的朋友可以参考下...2020-06-25
基于Silverlight打印的使用详解,是否为微软的Bug问题
本篇文章对Silverlight打印的使用进行了详细的分析介绍,需要的朋友参考下...2020-06-25浅谈C#跨线程调用窗体控件(比如TextBox)引发的线程安全问题
下面小编就为大家分享一篇浅谈C#跨线程调用窗体控件(比如TextBox)引发的线程安全问题,具有很好的参考价值,希望对大家有所帮助...2020-06-25- 线程间操作无效:从不是创建控件“label1”的线程访问它...2020-06-25
- 在windows2003上通过IIS6.0部署一个silverlight网站与部署其他网站基本一致,但是有几点特别需要注意的地方,掌握了这几个小窍门,就可以轻松部署你的silverlight网站了。...2016-01-27
- 这篇文章主要为大家详细介绍了Silverlight实现跑马灯动画,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要介绍了Winform中如何跨线程访问UI元素,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...2020-12-08
- 这篇文章主要为大家详细介绍了Silverlight实现星星闪烁动画,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
解析Silverlight调用WCF/Rest异常的解决方法
本篇文章对Silverlight调用WCF/Rest异常的解决方法进行了详细的分析介绍,需要的朋友参考下...2020-06-25- 这篇文章主要介绍了Silverlight将图片转换为byte的实现代码,需要的朋友可以参考下...2020-06-25
silverlight用webclient大文件上传的实例代码
这篇文章介绍了silverlight用webclient大文件上传的实例代码,有需要的朋友可以参考一下...2021-09-22- 本文主要介绍了C# winform跨线程操作控件的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2022-06-08