所以我们的教授给了我们一个片段
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();}
并且惊讶地发现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,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方法调用.
例如,如果您尝试从后台线程设置文本框的文本…它将引发异常,并且您将需要使用Invoke模式使其工作.
总结以上是内存溢出为你收集整理的c# – ThreadPool如何直接访问另一个线程的控件?全部内容,希望文章能够帮你解决c# – ThreadPool如何直接访问另一个线程的控件?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)