使用匿名委托的Dispatcher.Invoke在Silverlight中可以工���,但在WPF中无法工作

10

在Silverlight 4中,我有一个自定义的服务类,其中包含一个异步的Completed事件。在Completed事件内部,我通过类似这样的方式获取返回的数据并调用一个populate方法:

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对我来说不是一个选项。


为什么标题中是“Dispatcher.Invoke”,而你实际询问的是“Dispatcher.BeginInvoke”?它们不一样... - The incredible Jan
2个回答

26

您需要指定一个明确的委托类型。只需使用 Action 即可。

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

然而,您可以通过以下方式避免必须关闭 args.Jobs 值:

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

这是因为在Silverlight中,单参数版本的Dispatcher.BeginInvoke与WPF中的不同。 在Silverlight中,它需要一个Action,这允许C#编译器将您的lambda隐式类型化为Action。在WPF中,它需要一个Delegate(类似于Winforms中的Control.BeginInvoke),因此C#编译器必须显式指定一个委托类型。


我现在遇到了这个错误:需要对象引用才能访问非静态字段、方法或属性“System.Windows.Threading.Dispatcher.BeginInvoke(System.Delegate, params object[])”。我将其分成两行以尝试查看导致错误的原因。var d = new Action(() => populateInbox(args.Jobs)); Dispatcher.BeginInvoke(d, args.Jobs); 错误发生在第二行。 - Edward J. Stembler
Dispatcher.BeginInvoke(d, new object[] { args.Jobs }); 也不起作用。 - Edward J. Stembler
1
@Edward: Dispatcher 不是一个静态类。你必须在具有 Dispatcher 属性的 UI 元素的上下文中调用此函数,或者将 Dispatcher 作为另一个参数传递进去。 - Adam Robinson
是的,你说得对。我正在尝试在Excel工作簿项目中使用WPF用户控件。WPF用户控件通过ElementHost托管在ActionPane中。该窗格在不具有Dispatcher属性的Ribbon控件中实例化。谢谢。 - Edward J. Stembler

2
在WPF和winforms中,您必须首先将其转换为MethodInvoker,否则您将会收到错误“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;
});

更多信息请参见:http://msdn.microsoft.com/zh-cn/library/system.windows.forms.methodinvoker.aspx


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接