我一直在研究如何做这个约一个星期,我仍然不确定正确的方法,在一些例子中,我看到Thread类在其他人中使用,我看到Invoke被使用,这让我很困惑出价。
我在c#中有一个GUI程序,它包含一个textBox,用于向用户提供信息。
我面临的问题是我不知道如何从另一个在另一个线程上运行的类向textBox追加文本。如果有人能告诉我一个有效的例子,那对我有很大帮助。
最诚挚的问候!
答案 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