我聽說該線程無法直接訪問其他線程的控件。ThreadPool如何直接訪問另一個線程的控件?
因此,我們的教授給我們一個片段
private void UpdateUI()
{
if(this.InvokeRequired)
this.Invoke(new MethodInvoker(UpdateUI));
else
this.Refresh();
}
,並表示InvokeRequired
屬性返回false它的線程是不是控制的所有者,那麼,我們應該呼籲Invoke()
方法來告訴主人線程來執行UpdateUI()
方法。然後更新UI。
但最近,出於好奇我評論InvokeRequired
和Invoke()
private void UpdateUI()
{
//if(this.InvokeRequired)
//this.Invoke(new MethodInvoker(UpdateUI));
//else
this.Refresh();
}
,驚訝地看到,線程池可以訪問另一個線程的控制,現在我覺得我還沒有完全瞭解的概念線程池。
以下是完整的代碼。
using System;
using System.Threading;
using System.Drawing;
using System.Windows.Forms;
class MainForm : Form
{
public MainForm()
{
this.Text = "Hello WinForms";
ThreadPool.QueueUserWorkItem(Clock);
}
private void Clock(object state)
{
for(;;)
{
Thread.Sleep(1000);
UpdateUI();
}
}
private void UpdateUI()
{
//if(this.InvokeRequired)
// this.Invoke(new MethodInvoker(UpdateUI));
//else
this.Refresh();
}
protected override void OnPaint(PaintEventArgs pe)
{
using(Pen pen = new Pen(Color.Red, 2))
pe.Graphics.DrawRectangle(pen, 20, 20, 125, 30);
pe.Graphics.DrawString(DateTime.Now.ToString(), this.Font, Brushes.Blue, 25, 30);
}
[STAThread]
public static void Main()
{
Application.Run(new MainForm());
}
}
請問有人能解釋我是怎麼發生的?
謝謝。
+1,@Searock你可以通過在'OnPaint'方法中調用'Console.WriteLine(Thread.ManagedThreadId)'來看到效果,所以你會看到它只從UI線程調用。 –