在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
对我来说不是一个选择。
答案 0 :(得分:26)
您需要指定显式委托类型。只需使用Action
。
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#编译器必须明确指定委托类型。
答案 1 :(得分: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