是否System.Windows.Threading.Dispatcher
适用于WinForms
应用程序的UI线程?
如果是,为什么?它来自WindowsBase.dll,它似乎是一个WPF
组件.
如果没有,我如何调用工作单元回到UI线程?我发现Control.BeginInvoke()
,但创建一个控件只是为了引用原始线程似乎很笨拙.
您Dispatcher
甚至可以在WinForms应用程序中使用.
如果您确定要在UI线程上(例如在button.Click处理程序中),则为Dispatcher.CurrentDispatcher
您提供UI线程调度程序,您可以在以后使用该线程调度程序像往常一样从后台线程分派到UI线程.
Dispatcher是一个WPF组件,而不是WinForms组件.
如果要在UI线程上调度工作项,则必须使用已经找到的Control.BeginInvoke,或者跨线程对ResetEvents/WaitObjects做出反应.
通常在UI线程上调用工作项是件坏事,除非它是UI工作(即更新控件的内容或其他东西),在这种情况下Control.BeginInvoke()就足够了.
我提供了一个System.Windows.Threading.Dispatcher
在Windows窗体中使用的示例,在我对您的问题的上一个答案之后的问题 "使用WinForms上的TPL进行并行编程" 的回答中:
如果你肯定是在UI线程中(例如在一个button.Click处理程序中),Dispatcher.CurrentDispatcher为你提供了UI线程调度程序,你可以像往常一样从后台线程调度到UI线程.
是误导或混淆或缺乏具体的使用背景:
button.Click
处理程序不保证在UI线程上;
如果你不在UI线程上,仍然可以使用WinForms表单的UI线程的调度程序
可以获得WinForm UI线程的调度程序:
Dispatcher dispatcherUI = Dispatcher.CurrentDispatcher;
在按钮单击事件处理程序或其他任何位置(在窗体构造函数中)
然后用它来从其他线程UI执行,见下文对示例的详细信息我的答案:
private void button1_Click(object sender, EventArgs e) { Dispatcher dispUI = Dispatcher.CurrentDispatcher; for (int i = 2; i < 20; i++) { int j = i; var t = Task.Factory.StartNew (() => { var result = SumRootN(j); dispUI.BeginInvoke (new Action (() => richTextBox1.Text += "root " + j.ToString() + " " + result.ToString() + Environment.NewLine ) , null ); } ); }