gpt4 book ai didi

c# - ThreadPool如何直接访问另一个线程的控件呢?

转载 作者:行者123 更新时间:2023-11-30 14:16:52 25 4
gpt4 key购买 nike

听说线程不能直接访问其他线程的控件。

所以我们的教授给了我们一个片段

private void UpdateUI()
{
if(this.InvokeRequired)
this.Invoke(new MethodInvoker(UpdateUI));
else
this.Refresh();
}

并说 InvokeRequired 属性返回 false 如果线程不是控件的所有者,那么我们应该调用 Invoke() 方法来告诉所有者线程执行UpdateUI() 方法。然后更新 UI。

但最近,出于好奇,我评论了 InvokeRequiredInvoke()

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());
}
}

谁能解释一下这是怎么发生的?

谢谢。

最佳答案

在您发布的应用程序中,您没有从 ThreadPool 访问任何控件,您只是在表单上调用 Refresh。这实际上向表单发送了一条消息,告诉它自己重绘自己,但该消息是在主 GUI 线程上接收的,而不是从 ThreadPool 线程接收的。

因此,您不需要在您的案例中调用,因为您没有执行任何跨线程事件。 OnPaint 方法通过 Windows 消息泵间接调用,而不是直接从 Refresh 方法调用。

如果您要尝试,例如,从后台线程设置文本框的文本...它会抛出异常,并且您需要使用调用模式才能使其工作。

关于c# - ThreadPool如何直接访问另一个线程的控件呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6805389/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com