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).
    

      

  • 相关阅读:
    Nginx负载均衡+代理+ssl+压力测试
    Nginx配置文件详解
    HDU ACM 1690 Bus System (SPFA)
    HDU ACM 1224 Free DIY Tour (SPFA)
    HDU ACM 1869 六度分离(Floyd)
    HDU ACM 2066 一个人的旅行
    HDU ACM 3790 最短路径问题
    HDU ACM 1879 继续畅通工程
    HDU ACM 1856 More is better(并查集)
    HDU ACM 1325 / POJ 1308 Is It A Tree?
  • 原文地址:https://www.cnblogs.com/zitjubiz/p/11531679.html
Copyright © 2011-2022 走看看