zoukankan      html  css  js  c++  java
  • WinForm中的多线程

    •   使用BeginInvoke或Invoke
      • 作用
        • 在自己创建的非UI线程中,进行UI操作,比如更新UI上控件的状态。
        • Windows 窗体中的控件被绑定到特定的线程,不具备线程安全性。因此,如果从另一个线程调用控件的方法,那么必须使用控件的一个 Invoke 方法来将调用封送到适当的线程。
        • 如果已经创建控件的句柄,则除了 InvokeRequired 属性以外,控件上还有四个可以从任何线程上安全调用的方法,它们是: Invoke、BeginInvoke、 EndInvoke 和 CreateGraphics。 在后台线程上创建控件的句柄之前调用 CreateGraphics 可能会导致非法的跨线程调用。 对于所有其他方法调用,当从另一个线程进行调用时,应使用这些 Invoke 方法之一。如果控件句柄尚不存在,则 InvokeRequired 沿控件的父级链搜索,直到它找到有窗口句柄的控件或窗体为止。 如果找不到合适的句柄, InvokeRequired 方法将返回 false。
      • 也可以new一个Thread,在其中再使用BeginInvoke或Invoke
        • 这其实就是在自己创建的非UI线程中,又有一部分逻辑是要修改主UI线程的显示,那么就要用BeginInvoke来实现
        • Thread t = new Thread(() =>
                      {
                          // business logic
          
                          this.BeginInvoke(new Action(delegate ()
                          {
                             // ui logic
                          }));
          
                          // business logic
          
                          this.BeginInvoke(new Action(delegate ()
                          {
                             // ui logic
                          }));
                      });
                      t.Start();
          View Code
      • 每个控件都有new、active、disposed三个状态
      • 调用前的检查
        • 否则可能会导致异常:Invoke or BeginInvoke cannot be called on a control until the window handle has been created. (在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke)
        • 因此需要一些属性用于确定是否必须调用 Invoke 方法,当不知道什么线程拥有控件时这很有用
          • InvokeRequired
            • 最好在调用的外层套一个InvokeRequired来判断当前是否必须使用Invoke或者BeginInvoke来做动作,为false时即可以直接做动作
            • 这意味着如果不需要 Invoke(调用发生在同一线程上),或者如果控件是在另一个线程上创建的但尚未创建控件的句柄,则InvokeRequired 可以返回 false。如果尚未创建控件的句柄,您就不能简单地在控件上调用属性、方法或事件。这可能导致在后台线程上创建控件的句柄,从而隔离不带消息泵的线程上的控件并使应用程序不稳定。
          • IsHandleCreated
            • 谨慎起见,还可以使用IsHandleCreated来判断该控件是否已经创建了关联的句柄
            • 当 InvokeRequired 在后台线程上返回 false 时,您也可以通过检查 IsHandleCreated 的值来避免上面这种情况。 如果尚未创建控件句柄,您必须等到控件句柄已创建,才能调用 Invoke 或 BeginInvoke。 通常,仅当在应用程序主窗体的构造函数中创建了后台线程时(如同在 Application.Run(new MainForm()) 中),在已经显示窗体或取消 Application.Run 之前,才会发生这种情况
          • 单从检查的角度来说,事实上IsHandleCreate比InvokeRequired要严格,前者为true时,后者肯定是true???;InvokeRequired为false的原因可能是IsHandleCreate为false或者根本不需要Invoke等。
          • 两者的用途不太一样,一个用于判断有没有必要使用Invoke等,一个用于判断控件是否有句柄,虽然两者存在上述关系,所以最好两个属性都进行判断,先后顺序个人感觉无所谓
          •  1 if(control.IsDisposed || (!control.IsHandleCreated && !control.FindForm().IsHandleCreated))
             2 {
             3     // some exceptional condition:
             4     // handle in whatever way is appropriate for your app
             5     return;
             6 }
             7 
             8 if(control.InvokeRequired)
             9 {
            10     control.Invoke(action);
            11 }
            12 else
            13 {
            14     action();
            15 }
            View Code
      •  参考
        • https://www.cnblogs.com/slyzly/articles/2121436.html
        • https://blog.csdn.net/dyllove98/article/details/9105555
  • 相关阅读:
    一款新型的智能家居WiFi选择方案——SimpleWiFi在无线智能家居中的应用
    智能手机的工业控制应用方案——SimpleWiFi在工业控制领域应用
    一种单片机支持WiFi的应用——SimpleWiFi在单片机中的应用
    TI推出SimpleLink低能耗蓝牙CC2541
    SimpleWiFi模块评估板
    Android架构设计和软硬整合完整训练
    CentOS上解压ZIP乱码的解决办法
    更具体的描述JNI
    数据市中心全省中国mysql脚本
    几种方法枚举子集
  • 原文地址:https://www.cnblogs.com/wyp1988/p/9888808.html
Copyright © 2011-2022 走看看