10

在 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;
}

BeginInvokeSL4 中工作,但是当我将它移植到 WPF 时,我收到以下错误:

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

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

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

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

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

4

2 回答 2

26

您需要指定显式委托类型。只需使用Action.

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

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

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

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

于 2010-07-19T19:59:49.490 回答
2

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

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

欲了解更多信息:http: //msdn.microsoft.com/en-us/library/system.windows.forms.methodinvoker.aspx

于 2011-04-15T21:13:20.627 回答