C#GUI应用程序,来自另一个更新UI的线程的另一个类

时间:2010-10-30 07:49:40

标签: c# multithreading user-interface class

我一直在研究如何做这个约一个星期,我仍然不确定正确的方法,在一些例子中,我看到Thread类在其他人中使用,我看到Invoke被使用,这让我很困惑出价。

我在c#中有一个GUI程序,它包含一个textBox,用于向用户提供信息。

我面临的问题是我不知道如何从另一个在另一个线程上运行的类向textBox追加文本。如果有人能告诉我一个有效的例子,那对我有很大帮助。

最诚挚的问候!

3 个答案:

答案 0 :(得分:8)

易:

MainWindow.myInstance.Dispatcher.BeginInvoke(new Action(delegate() {MainWindow.myInstance.myTextBox.Text = "some text";});

WHERE MainWindow.myInstance是一个设置为MainWindow实例的公共静态变量(应该在构造函数中设置,并且在构造实例之前将为null)。

好的,在一行中有很多让我重复一遍:

当您想要更新UI控件时,正如您所说,您必须从UI线程执行此操作。内置了将委托(方法)传递给UI线程的方法:Dispatcher。我使用MainWindow.myInstance(因为所有UI组件)都包含对Dispatcher的引用 - 您也可以在自己的变量中保存对Dispatcher的引用:

Dispatcher uiDispatcher = MainWindow.myInstance.Dispatcher;

拥有Dispatcher之后,您可以通过Invoke()传递一个委托来在UI线程上运行BeginInvoke()。唯一的区别是Invoke()只会在委托运行后返回(即在你的情况下已经设置了TextBox的Text),而BeginInvoke()将立即返回,因此你调用的其他线程可以继续(Dispatcher将运行)你的代表很快就可以直接离开了。)

我通过了一位匿名代表:

delegate() {myTextBox.Text = "some text";}

{}之间的位是方法块。这称为匿名,因为只创建了一个并且它没有名称 - 但我可以实例化一个委托:

Action myDelegate = new Action(UpdateTextMethod);

void UpdateTextMethod() 
{
    myTextBox.Text = "new text";
}

然后通过了:

uiDispatcher.Invoke(myDelegate);

我还使用了Action类,它是一个内置的委托,但你可以创建自己的代码 - 你可以在MSDN上阅读更多关于代理的信息,因为这有点偏离主题..

答案 1 :(得分:0)

听起来你正在使用后台线程进行处理,但是想要保持UI响应? BackgroundWorker听起来像票:

  

BackgroundWorker类允许您   在一个单独的,   专用线程。耗时的   下载和数据库等操作   交易可能会导致您的用户   界面(UI)看起来好像它   他们已经停止了回应   运行。当您需要响应式UI时   你面临着长时间的拖延   与此类操作相关联的   BackgroundWorker类提供了一个   方便的解决方案。

答案 2 :(得分:0)

只需使用BackgroundWorker即可。它很简单,消除了管理自己的线程的痛苦。更多信息,您可以看到:http://dotnetperls.com/backgroundworker