入門示例: 假若有一個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).