Я слышал, что поток не может получить доступ к элементам управления других потоков напрямую.
Итак, наш профессор дал нам фрагмент
private void UpdateUI()
{
if(this.InvokeRequired)
this.Invoke(new MethodInvoker(UpdateUI));
else
this.Refresh();
}
и сказал, что свойство InvokeRequired
возвращает false в потокене является владельцем элемента управления, и тогда мы должны вызвать метод Invoke()
, чтобы сообщить потоку владельца выполнить метод UpdateUI()
.Который затем обновляет пользовательский интерфейс.
Но недавно, просто из любопытства я прокомментировал InvokeRequired
и Invoke()
private void UpdateUI()
{
//if(this.InvokeRequired)
//this.Invoke(new MethodInvoker(UpdateUI));
//else
this.Refresh();
}
и был удивлен, увидев, что ThreadPool может получить доступ к элементам управления другого потокаи теперь я чувствую, что не совсем понял концепцию ThreadPool.
Вот полный код.
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());
}
}
Может кто-нибудь объяснить, как это происходит?
Спасибо.