2013-05-21 38 views
0

我知道,从另一个线程是最简单的方法来更新标签:从C#中的另一个线程更新GUI - 切换回主线程?

void DoSomething() 
{ 
    if (InvokeRequired) 
    { 
     Invoke(new MethodInvoker(DoSomething)); 
    } else 
    { 
     // Do Something 
    } 
} 

我的问题是,如果不是需要更新从另一个线程的GUI的if的是有可能变回主线程并从那里更新GUI?

+2

请更好地解释你的问题。你想要完成什么? –

+2

'有可能改回主线程并从那里更新GUI',这是''Invoke'做的事情。 –

回答

3

其实,要做到这一点最简单的方法是

Invoke(new MethodInvoker(DoSomething)); 

,如果你从另一个线程是肯定的,即调用它。如果你知道,InvokeRequired将永远是真实的。

另外,您可以使用WinForms Timer来轮询文本字段的更改。该计时器在GUI线程中运行。如果每秒有数百个事件,那么这是一个非常好的解决方案。或者至少“很多”。这样你就没有太多的切换到GUI线程(总是需要相当长的时间)。

1

当然,它可能...您可以使用称为分派器(System.Windows.Threading)的类。这个类的主要目的是在线程上发送“请求/调用”...而对于GUI线程,这种调度器的实例可用于所有控件。你可以找到这个实例作为你的窗口的成员,例如...

这个问题是你使用调度器alraedy(在你发布的代码中)以某种方式...如果你调用内部调用表单这个默认的/ gui调度器用来。而且“IF”可以减少gui线程本身的调用次数。

它的工作原理是“我是否在ui线程中?否?然后在调度器请求在UI线程中调用此相同的方法!...我是否在UI Thred?是的!好吧,我正在做一些事情。

如果你100%确定你调用这个表单而不是UI线程,你可以扔掉那个IF并直接调用调度器。

MyForm.Dispatcher.Invoke(mydelegate, params[]) 

或使用一些拉姆达,而不是委托或MethodInvoker ...

MyForm.Dispatcher.BeginInvoke((Action)(()=>{ textbox.text = result; }), null); 

,并在所有...你可以存储(在例如form.load事件)参考UI调度使用在不同的类(一些工人阶级做其他的东西)

如果你创造一些更大的UI的东西,我的建议更优秀的用户界面和易于操作这样的东西是:...考虑WPF和MVVM模式和属性的一些研究改变通知....它会给你非常强大的工具机智h“自我更新”以及数据,工作线程和UI之间非常可扩展的UI和层。

+0

调度员是WPF,而不是WinForms! – JeffRSon

+0

是的,WinForms控件没有将调度程序公开为成员..但是,即使在WinForm中,仍然可以使用Dispatcher。 –

+0

它只是在线程上刨削“作业”的类。使用** Dispatcher.CurrentDispatcher()**可以检索耦合到当前线程的实例。可能需要引用WindowsBase。 –