多线程呼叫代表

时间:2012-06-21 11:18:08

标签: c# wpf multithreading

引用Marc Gravell:

///...blah blah updating files
string newText = "abc"; // running on worker thread
this.Invoke((MethodInvoker)delegate {
    someLabel.Text = newText; // runs on UI thread
});
///...blah blah more updating files

我希望使用WPF执行此操作,因此无法使用invoke方法。有什么想法吗?这个线程的东西正在我的脑袋:/

更详情

我开始使用新线程

Thread t = new Thread (LoopThread);
t.Start();
t.Join();

但是在整个LoopThread中,我想写一下UI。

更新

感谢Jon Skeet的Dispatcher.Invoke位。似乎MethodInvoker也是WinForms。 WPF等价?

更新2

感谢Adriano使用System.Windows.Forms.MethodInvoker建议代替System.Action

(你们对this参数混淆是正确的,只需要构建以消除错误。)

自添加SimpleInvoke以来的总线,现在我用

命中
Extension method must be defined in a non-generic static class

就行了

public partial class MainWindow : Window

有什么想法吗?

3 个答案:

答案 0 :(得分:6)

在WPF中,您只需使用Dispatcher.Invoke代替Control.Invoke

DispatcherObject类(WPF类派生自此类)公开了Dispatcher属性,因此您只需要:

Dispatcher.Invoke((Action) delegate {
    someLabel.Text = newText; // runs on UI thread
});

如果您使用的是C#3或更高版本(以及.NET 3.5或更高版本),则可能需要向DispatcherObject添加扩展方法:

// Make this a new top-level class
public static class DispatcherObjectExtensions
{
    public static void SimpleInvoke(this DispatcherObject dispatcherObject,
                                    Action action)
    {
        dispatcherObject.Dispatcher.Invoke(action);
    }
}

所以你可以使用:

// From within your UI code
this.SimpleInvoke(() => someLabel.Text = newText);

答案 1 :(得分:0)

使用SynchronizationContext进行妥协:

    // gui thread

    var sc = SynchronizationContext.Current;

// work thread

    sc.Post(s => 
    {
    someLabel.Text = newText
    }, null);

答案 2 :(得分:-1)

继续Jon Skeet发表评论,您可以在下面打电话给您的分机

DispatcherObject.SimpleInvoke(() => someLabel.Text = newText);