• WPF笔记12: 线程处理模型


    WPF笔记12: 线程处理模型

    本文摘要:

    1:理解与UI相关的多线程操作;

    2:多个窗口多个线程

    1:理解与UI相关的多线程操作

        首先来说说传统Winform。我们知道传统Winform新起工作线程,在工作线程中不能对界面元素进行操作。如下面的代码,运行会报错“线程间操作无效: 从不是创建控件“label1”的线程访问它。”:

                Thread t = new Thread(delegate()
                    {
                        label1.Text = "temp";
                    });
                t.Start();

         要使上面的代码能成功运行,我们需要使用控件的InvokeBeginInvoke和方法。这两个方法的意思是说,让赋值这个行为交给UI线程去处理。代码如下:

                Thread t = new Thread(delegate()
                    {
                        label1.Invoke(new MethodInvoker(delegate()
                        {
                            label1.Text = "temp";
                        }));
                    });
                t.Start();

         而WPF的控件,我们找不到InvokeBeginInvoke这两个方法了。因为WPF的UI线程都交给一个叫做调度器的类了。

         WPF 应用程序启动时具有两个线程:一个用于处理呈现,另一个用于管理 UI。 呈现线程实际上隐藏在后台运行,而 UI 线程则接收输入、处理事件、绘制屏幕以及运行应用程序代码。UI 线程在一个名为 Dispatcher 的对象中将工作项进行排队。 Dispatcher 根据优先级选择工作项,并运行每一个工作项直到完成。Dispatcher 类提供两种注册工作项的方法:InvokeBeginInvoke。 这两个方法都会安排执行一个委托。Invoke 是同步调用,即它直到 UI 线程实际执行完该委托时才返回。BeginInvoke 是异步调用,因而将立即返回。

         上面的代码在WPF中的实现如下:

                Thread t = new Thread(new ThreadStart( delegate
                {
                    tb_test.Dispatcher.Invoke(new Action(delegate
                       { 
                           tb_test.Text = "123"; 
                       }), null);
                }));
                t.Start();
    

         注意,WPF中已经没有MethodInvoker这个类,我们使用Action代替。当然,你也可以使用自定义的委托声明。

    2:多个窗口多个线程

        一些 WPF 应用程序需要多个顶级窗口。 一个线程/Dispatcher 组合管理多个窗口完全可以接受,但有时使用多个线程更佳。 特别是在其中一个窗口有可能独占线程时,采用多个线程的优点更为突出。

        Windows 资源管理器即采用这种工作方式。 每个新的资源管理器窗口都属于原始进程,但每个此类窗口都是在一个独立线程的控制下创建的。该例子的简单模仿如下代码:

            private void NewWindowHandler(object sender, RoutedEventArgs e)
            {       
                Thread newWindowThread = new Thread(new ThreadStart(ThreadStartingPoint));
                newWindowThread.SetApartmentState(ApartmentState.STA);
                newWindowThread.IsBackground = true;
                newWindowThread.Start();
            }
    
            private void ThreadStartingPoint()
            {
                Window1 tempWindow = new Window1();
                tempWindow.Show();       
                System.Windows.Threading.Dispatcher.Run();
            }



    返回导读目录,阅读更多随笔



    分割线,以下为博客签名:

    软件臭虫情未了
    • 编码一分钟
    • 测试十年功


    随笔如有错误或不恰当之处、为希望不误导他人,望大侠们给予批评指正。

  • 相关阅读:
    展示之前的作品
    let和const的一些知识点
    javascript执行上下文和变量对象
    数据类型隐式转换及数据类型判断方式总结
    CSS元素隐藏方法总结
    ES6 —— 数组总结
    小程序性能相关
    nginx和resin一二三
    修改XAMPP的默认根目录
    面试题延伸及总结
  • 原文地址:https://www.cnblogs.com/08shiyan/p/1846721.html
Copyright © 2020-2023  润新知