为什么在 WPF 中使用 Dispatcher.Invoke((ThreadStart)delegate...?

发布于 12-17 02:33 字数 313 浏览 0 评论 0原文

当我需要从后台线程访问某些 UI 元素时,我通常使用 Dispatcher.Invoke。最近,我不得不更改其他人的书面来源,我看到他通过以下结构完成了相同的任务:

Dispatcher.Invoke((ThreadStart)delegate
            {
              //some code that uses controls from UI
            });

我什么时候应该使用这样的代码而不是 Dispatcher.Invoke/BeginInvoke ,为什么?

I usually use Dispatcher.Invoke when i need to access some UI elements from background thread. Recently i had to change other's written sources and i saw that same tasks he accomplishes with constructions like:

Dispatcher.Invoke((ThreadStart)delegate
            {
              //some code that uses controls from UI
            });

When should i use such code instead of Dispatcher.Invoke/BeginInvoke and why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你在我安2024-12-24 02:33:32

确实使用了Dispatcher.Invoke - 它不是“代替”。该代码只是使用 ThreadStart 来告诉编译器将匿名方法转换为的委托类型。

它相当于:

ThreadStart tmp = delegate
{
    // Code
};
Dispatcher.Invoke(tmp);

就我个人而言,我会在此处使用 Action 而不是 ThreadStart,因为您实际上并未启动线程,但这是一个非常任意的选择。忽略它被称为 ThreadStart 的事实 - 它只是一个具有 void 返回类型且没有参数的委托。

编辑:您必须指定 a 委托类型的原因是编译器无法将匿名函数(即匿名方法或 lambda 表达式)转换为 Delegate,这是Dispatcher.Invoke 的参数类型。

解决此问题的一种方法是编写一个扩展方法:

public static void InvokeAction(this Dispatcher dispatcher, Action action)
{
    dispatcher.Invoke(action);
}

然后您可以使用:

foo.Dispatcher.InvokeAction(() => { /* stuff */ });

并且编译器知道将 lambda 表达式转换为 Action

That does use Dispatcher.Invoke - it's not an "instead of". That code is just using ThreadStart as a way of telling the compiler the delegate type to convert the anonymous method to.

It's equivalent to:

ThreadStart tmp = delegate
{
    // Code
};
Dispatcher.Invoke(tmp);

Personally I'd use Action instead of ThreadStart here as you're not actually starting a thread, but it's a pretty arbitrary choice. Ignore the fact that it's called ThreadStart - it's just a delegate with a void return type and no parameters.

EDIT: The reason you have to specify a delegate type is that the compiler can't convert an anonymous function (i.e. an anonymous method or a lambda expression) to just Delegate, which is the argument type of Dispatcher.Invoke.

One workaround for this is to write an extension method:

public static void InvokeAction(this Dispatcher dispatcher, Action action)
{
    dispatcher.Invoke(action);
}

You can then use:

foo.Dispatcher.InvokeAction(() => { /* stuff */ });

and the compiler knows to convert the lambda expression to Action.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文