使用匿名委托的 Dispatcher.Invoke 在 Silverlight 中工作,但在 WPF 中不起作用

发布于 2024-09-10 12:00:58 字数 755 浏览 11 评论 0原文

在 Silverlight 4 中,我有一个自定义服务类,它有一个异步 Completed 事件。在 Completed 事件中,我获取返回的数据并通过如下方式调用填充方法:

private void service_Completed(object sender, CompletedEventArgs args)
{
    Dispatcher.BeginInvoke(() => populateInbox(args.Jobs));
}

private void populateInbox(List<JobViewModel> jobs)
{
    inbox.DataContext = jobs;
}

BeginInvoke 在 SL4 中工作,但是当我将其移植到 WPF 时,出现以下错误:

无法将 lambda 表达式转换为“System.Delegate”类型,因为它不是委托类型

我尝试将其更改为内联、匿名、参数化委托:

Dispatcher.BeginInvoke(delegate(List<JobViewModel> jobs)
{
    inbox.DataContext = jobs;
});

但是,这会产生相同的编译时错误。

知道如何让它在 WPF 中工作吗?重构以使用 BackgroundWorker 对我来说不是一个选择。

In Silverlight 4 I have a custom service class which has an asynchronous Completed event. Inside the Completed event I take the returned data and invoke a populate method via something like this:

private void service_Completed(object sender, CompletedEventArgs args)
{
    Dispatcher.BeginInvoke(() => populateInbox(args.Jobs));
}

private void populateInbox(List<JobViewModel> jobs)
{
    inbox.DataContext = jobs;
}

The BeginInvoke works in SL4, however when I ported it to WPF I get the following error:

Cannot convert lambda expression to type 'System.Delegate' because it is not a delegate type

I tried changing it to an in-line, anonymous, paramaterized delegate:

Dispatcher.BeginInvoke(delegate(List<JobViewModel> jobs)
{
    inbox.DataContext = jobs;
});

However, that yields the same compile-time error.

Any idea how to get this to work in WPF? Refactoring to use the BackgroundWorker is not an option for me.

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

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

发布评论

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

评论(2

ゞ花落谁相伴 2024-09-17 12:00:58

您需要指定显式委托类型。只需使用操作

Dispatcher.BeginInvoke(new Action(() => populateInbox(args.Jobs));

但是,您可以避免像这样关闭 args.Jobs 值:

Dispatcher.BeginInvoke(new Action((jobs) => populateInbox(jobs)), jobs);

这是因为单参数版本的 Dispatcher.BeginInvoke 在 Silverlight 中具有不同的签名比在 WPF 中。在 Silverlight 中,它需要一个 Action,它允许 C# 编译器将 lambda 隐式键入为 Action。在 WPF 中,它需要一个 Delegate(就像 Winforms 中的 Control.BeginInvoke 类似物),因此 C# 编译器必须显式指定一个委托类型。

You need to specify an explicit delegate type. Just use an Action.

Dispatcher.BeginInvoke(new Action(() => populateInbox(args.Jobs));

You could, however, avoid having to close over the args.Jobs value like this:

Dispatcher.BeginInvoke(new Action((jobs) => populateInbox(jobs)), jobs);

This is because the single-parameter version of Dispatcher.BeginInvoke has a different signature in Silverlight than in WPF. In Silverlight, it takes an Action, which allows the C# compiler to implicitly type your lambda as an Action. In WPF, it takes a Delegate (like its Control.BeginInvoke analog in Winforms), so the C# compiler has to have a delegate type explicitly specified.

小嗲 2024-09-17 12:00:58

在 WPF 和 winforms 中,您必须首先将其转换为 MethodInvoker,否则您将收到错误无法将匿名方法转换为类型“System.Delegate”,因为它不是委托类型。

Dispatcher.BeginInvoke((MethodInvoker) delegate(List<JobViewModel> jobs)
{
   inbox.DataContext = jobs;
});

有关详细信息:< a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.methodinvoker.aspx" rel="nofollow">http://msdn.microsoft.com/en-us/库/system.windows.forms.methodinvoker.aspx

In WPF and winforms you must cast it to a MethodInvoker first, otherwise you will get the error Cannot convert anonymous method to type 'System.Delegate' because it is not a delegate type.

Dispatcher.BeginInvoke((MethodInvoker) delegate(List<JobViewModel> jobs)
{
   inbox.DataContext = jobs;
});

For more info: http://msdn.microsoft.com/en-us/library/system.windows.forms.methodinvoker.aspx

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