多线程学习笔记(一) 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上的控件的,只能经过委托,让UI线程来修改.this

        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个线程把修改控件属性的操做交给委托, 最后再UpdateUIspa

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).
相关文章
相关标签/搜索