zoukankan      html  css  js  c++  java
  • 多线程学习笔记(一) InvokeRequired 和 delegate

    入门示例: 假如有一个label,我们希望像走马灯一样,从1显示到100

            private void button1_Click(object sender, EventArgs e)
            {
                for (int i = 0; i <= 100; i++)
                {
                    label1.Text = i.ToString();
                }
     
            }

    但这种写法,只会卡一下,然后label显示100,没有变化的. 如果用doEvents,就可以变化了

            private void button1_Click(object sender, EventArgs e)
            {
                for (int i = 0; i <= 100; i++)
                {
                    label1.Text = i.ToString();
                    Thread.Sleep(50);
                    Application.DoEvents();
                }
     
            }

    但是stackoverflow里说Application.DoEvents是为了适应vb项目迁移而设的,尽量不推荐使用

    改成多线程,子线程是不能直接修改UI上的控件的,只能通过委托,让UI线程来修改.

            delegate void D(object obj);
            private void button2_Click(object sender, EventArgs e)
            {
    
                for (int i = 0; i < 10; i++)
                {
                    Thread t = new Thread(new ParameterizedThreadStart(SetTextBoxValue));
                    t.IsBackground = true;
                    t.Start(i.ToString());
                    Debug.WriteLine("Thread #"+ i +" Start");
                }
            }
    
            void SetTextBoxValue(object obj)
            {
                if (label1.InvokeRequired)
                {
                    Debug.WriteLine("Thread #" + obj + "InvokeRequired,set Delegate");
                    D d = new D(SetTextBoxValue);
                    label1.Invoke(d, obj); //异步的话,不保证哪个线程先完成.最后的结果是8或9
                }
                else
                {
                    Debug.WriteLine("Thread #" + obj + " UI Change ");
              //An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll
                    //Additional information: 线程间操作无效: 从不是创建控件“label1”的线程访问它。
                    this.label1.Text = obj.ToString();
                    Thread.Sleep(50);
                    
    
                }
            }

    debug的输出如下: 启动10个线程.10个线程把修改控件属性的操作交给委托, 最后再UpdateUI

    Thread #0 Start
    Thread #0InvokeRequired,set Delegate
    The thread 0x19ec has exited with code 259 (0x103).
    Thread #1 Start
    Thread #1InvokeRequired,set Delegate
    The thread 0x570 has exited with code 259 (0x103).
    Thread #2 Start
    Thread #2InvokeRequired,set Delegate
    The thread 0x1d04 has exited with code 259 (0x103).
    Thread #3 Start
    Thread #4 Start
    Thread #4InvokeRequired,set Delegate
    The thread 0x1a8c has exited with code 259 (0x103).
    Thread #5InvokeRequired,set Delegate
    Thread #3InvokeRequired,set Delegate
    The thread 0x1a88 has exited with code 259 (0x103).
    The thread 0xedc has exited with code 259 (0x103).
    Thread #5 Start
    Thread #6 Start
    Thread #7 Start
    Thread #7InvokeRequired,set Delegate
    Thread #6InvokeRequired,set Delegate
    The thread 0x1b58 has exited with code 259 (0x103).
    The thread 0x694 has exited with code 259 (0x103).
    Thread #8InvokeRequired,set Delegate
    The thread 0x1680 has exited with code 259 (0x103).
    Thread #8 Start
    Thread #9 Start
    Thread #0 UI Change 
    Thread #9InvokeRequired,set Delegate
    The thread 0x177c has exited with code 259 (0x103).
    Thread #1 UI Change 
    Thread #2 UI Change 
    Thread #4 UI Change 
    Thread #5 UI Change 
    Thread #3 UI Change 
    Thread #7 UI Change 
    Thread #6 UI Change 
    Thread #8 UI Change 
    Thread #9 UI Change 
    The thread 0x67c has exited with code 0 (0x0).
    

      

  • 相关阅读:
    ubuntu开启SSH服务
    Ubuntu修改虚拟内存(即swap空间)
    【转】Ubuntu 13.10中MyEclipse 10.6+下载+安装+破解
    【转】 ubuntu下安装mysql
    【转】 Ubuntu 11.04 下安装配置 JDK 7
    Linux非root用户安装jdk和tomcat
    algorithm之改变序列算法--待解决
    时间日期设置--ctime头文件
    C中的一些函数
    algorithm之不变序列操作
  • 原文地址:https://www.cnblogs.com/zitjubiz/p/11531679.html
Copyright © 2011-2022 走看看