zoukankan      html  css  js  c++  java
  • C# 优雅的解决 多线程中访问 UI 的问题

    优雅的解决 多线程中访问 UI 的问题

    1.在WinForm 程序中可以在Form的构造函数中. 将 "是否检察跨线程的控件访问" 设为 False. 就解决了. 就可以正常的使用控件了.

      Control.CheckForIllegalCrossThreadCalls = false;

    2. 就是使用控件的Invoke 方法 

    比如:

      label1.Invoke(new MethodInvoker(delegate () {this.label1.text = "靠...!";}));

    使用Lambda 表达示会更优雅一点:

      label1.Inovke(new MethodInvoker( () => this.lable1.text = "哈哈.."));

    这是我常用的. 觉得算得上优雅的方法. 如果还有朋友知道列优雅的方法,请留言告知~~!

    ----------------------------------------------2012.11.17 日补充--------------------------------------------

    在使用 线程或是使用异步的方法去改变 DataGridView 控件时.. 如果直接使用第一种方法.直接允许控制跨线程访问的话.  会有这样的问题(很是恼人) :

    用delegate的BeginInvoke去更新DataGridView时,当异步调用完成后有这样现象:
    1.如果更新后DataGridView没有出现滚动条,程序会正常运行
    2.如果更新后DataVridView出现了滚动条,程序会卡死

    解决的方法是 不要使用 第一种方法: 这种方法 虽然方便.. 但会带来一些意料不到的问题. 还是这样来更新控件:

    label1.Inovke(new MethodInvoker( () => this.lable1.text = "哈哈.."));

    这个MethodInvoker只是一个 返回值,无参数的代理而已. 所以你也可能 自己定义一个 比如: public delegate void MyInvoker(); 然后使用

    label1.Inovke(new MyInvoker( () => this.lable1.text = "哈哈.."));  是一样的.

    同样你也可以 使用 Action

    label1.Inovke(new Action( () => this.lable1.text = "哈哈.."));

    而且. 可以通过  Control.InvokeRequired 方法 ,来判断,当前访问这个控件的线程 是否是UI线程.是否需要使用 Invoke方法.

    if (this.dgv.InvokeRequired) {
      this.dgv.Invoke(new MethodInvoker(()=>dgv.DataSource = ds.Tables[0]));
    } else { // 如果是 UI 主线程更新的话
      this.dgv.DataSource = ds.Tables[0];
    }

    关于Invoke的拥有者:Control
    因为Control.Invoke含义是将方法委托给 *拥有该Control* 的线程去执行。因些.我们不需要使用 this.label1.Invoke 或是 this.DataGridView,Invoke 可以直接使用 : this.Invoke.  this 指针也就是当前的 UI 主线程.

    就好似 A 跟 B 说, 我不方便去你家, 你帮我用你家的电脑下点电影什么的. A 不允许直接使用 B的电脑. 但他可以让B帮他完成一些事情. B得到了 A的一些求助. 自己去使用属于自己的电脑.   这个比喻就充分的表达了.. 两个线程间的交流. 

    public void Method_A_Thread() {

      // Do something

         // 让UI线程帮忙完成些 ,属于 UI线程里的内容

         // this.Invoke(new Action(() => this.label.Text = "xxx"));

    }

  • 相关阅读:
    1026 Table Tennis (30)
    1029 Median
    1025 PAT Ranking (25)
    1017 Queueing at Bank (25)
    1014 Waiting in Line (30)
    1057 Stack (30)
    1010 Radix (25)
    1008 Elevator (20)
    字母大小写转换
    Nmap的基础知识
  • 原文地址:https://www.cnblogs.com/easyfrog/p/2343075.html
Copyright © 2011-2022 走看看