浅谈Silverlight 跨线程的使用详解

 更新时间:2013年05月14日 12:00:14   作者:  
本篇文章是对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();
        }

如果你运行程序,点击按钮,会得到下面的异常。

clip_image002

这个问题的原因很简单:一个线程尝试调用另一个线程的方法 解决这个异常的方式很简单,

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开发技巧之花式控件功能扩展详解

    WPF开发技巧之花式控件功能扩展详解

    这篇文章主要给大家介绍了关于WPF日常开发之花式控件功能扩展的相关资料,通过文中这个例子,我们可以对WPF的掌握会更深刻,需要的朋友可以参考下
    2021-07-07
  • c#下注册表操作的一个小细节

    c#下注册表操作的一个小细节

    c#下注册表操作的一个小细节...
    2007-11-11
  • C# Record构造函数的行为更改详解

    C# Record构造函数的行为更改详解

    C# 9 中的record类型是仅具有只读属性的轻量级、不可变数据类型(或轻量级类),下面这篇文章主要给大家介绍了关于C# Record构造函数的行为更改的相关资料,需要的朋友可以参考下
    2021-08-08
  • C#Button窗体常用属性及事件详解

    C#Button窗体常用属性及事件详解

    在本篇文章里小编给各位分享的是关于C#Button窗体常用属性及事件详解,需要的朋友们可以参考下。
    2020-03-03
  • C#超实用代码段合集

    C#超实用代码段合集

    这篇文章主要介绍了C#超实用代码段合集,涉及C#针对图标、数学运算、拼音、日期、时间及文件夹等的相关操作技巧,需要的朋友可以参考下
    2015-11-11
  • C#使用ADO.Net部件来访问Access数据库的方法

    C#使用ADO.Net部件来访问Access数据库的方法

    数据库的访问是所有编程语言中最重要的部分,C#提供了ADO.Net部件用于对数据库进行访问。本文从最简单易用的微软Access数据库入手讨论在C#中对数据库的访问。
    2015-09-09
  • C#实现发送手机验证码功能

    C#实现发送手机验证码功能

    之前基于c#实现手机发送验证码功能很复杂,真正做起来也就那回事,不过就是一个post请求就可以实现的东西,今天小编把思路分享到脚本之家平台,供大家参考下
    2017-06-06
  • WinForm单例窗体用法实例

    WinForm单例窗体用法实例

    这篇文章主要介绍了WinForm单例窗体,结合实例形式分析了窗体的单例模式定义、实现与使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2016-07-07
  • C#实现接收QQ邮件的示例代码

    C#实现接收QQ邮件的示例代码

    这篇文章主要为大家详细介绍了C#如何使用pop协议来实现一下接收QQ邮件的功能,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2022-08-08
  • Unity UGUI的MaskableGraphic可遮罩图形组件介绍使用

    Unity UGUI的MaskableGraphic可遮罩图形组件介绍使用

    这篇文章主要为大家介绍了Unity UGUI的MaskableGraphic可遮罩图形组件介绍使用,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07

最新评论