多线程/ C#:我可以在多个UI元素上执行BeginInvoke吗?

时间:2010-12-19 20:54:59

标签: c# wpf winforms multithreading

说我在工作线程上,我想更改几个UI元素,一个按钮,一个文本框等。

我是否需要在每个元素上调用BeginInvoke?即,

  myButton.BeginInvoke(someMethod);
  myTextBox.BeginInvoke(someOtherMethod);

或者有没有办法做一个BeginInvoke然后更新多个UI元素?感谢

3 个答案:

答案 0 :(得分:4)

不,这不是必需的。除非您的应用程序正在运行多个消息循环(极不可能,并且肯定知道它是否已知),否则您调用BeginInvoke的控件完全无关紧要;它所做的就是将委托和参数传递给一个队列,该队列作为消息循环的一部分进行处理。严格地说,控件的交互与你调用BeginInvoke的控件之间不需要任何关系。

答案 1 :(得分:3)

只需在表单上调用BeginInvoke并从那里更新所有控件。


@James Black:我的捷径是添加如下方法:

private IAsyncResult BeginInvoke(MethodInvoker method) {
    return BeginInvoke((Delegate)method);
}

然后称之为:

BeginInvoke(() => {
    txtName.Text = name;
});

答案 2 :(得分:0)

如果您可以使用并行扩展框架,我发现这有用:

TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();

我在构造函数中这样做了,所以我在主线程上。

然后我会打电话给Task这样做:     private void changeElements(){       (新任务(()=>       {         //做你更新       }))启动(uiScheduler);     }

通过这种方式,您可以执行所需的所有任务,并且在使用BeginInvoke时会删除大量额外代码,因为您不再需要委托。

但是,正如所指出的那样,您不必调用多个BeginInvoke调用来更新UI,因为在第一个调用之后,您已经在主线程上了。