1

引用 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

感谢阿德里亚诺建议而不是System.Windows.Forms.MethodInvoker使用System.Action.

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

自从添加了总线SimpleInvoke,现在我很喜欢

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

在线上

public partial class MainWindow : Window

有什么想法吗?

4

3 回答 3

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);
于 2012-06-21T11:19:20.527 回答
0

作为使用 SynchronizationContext 的妥协:

    // gui thread

    var sc = SynchronizationContext.Current;

// work thread

    sc.Post(s => 
    {
    someLabel.Text = newText
    }, null);
于 2012-06-21T22:35:14.870 回答
-1

继续 Jon Skeet 评论,您可以像下面这样调用您的分机

DispatcherObject.SimpleInvoke(() => someLabel.Text = newText);
于 2012-06-21T11:47:34.523 回答