当前位置: 移动技术网 > IT编程>开发语言>c# > 浅谈Silverlight 跨线程的使用详解

浅谈Silverlight 跨线程的使用详解

2019年07月18日  | 移动技术网IT编程  | 我要评论

新建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();

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网