Dispatcher.Invoke с анонимным делегатом работает в Silverlight, но не в WPF
В 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, я получаю следующую ошибку:
Невозможно преобразовать лямбда-выражение для типа 'System.Delegate', потому что это не тип делегата
Я попытался изменить его на встроенный, анонимный, параметризованный делегат:
Dispatcher.BeginInvoke(delegate(List<JobViewModel> jobs)
{
inbox.DataContext = jobs;
});
Однако это дает ту же ошибку времени компиляции.
Любая идея, как заставить это работать в WPF? Рефакторинг для использования BackgroundWorker
для меня не вариант.
Ответы
Ответ 1
Вам нужно указать явный тип делегата. Просто используйте Action
.
Dispatcher.BeginInvoke(new Action(() => populateInbox(args.Jobs));
Однако вы могли бы не закрывать значение args.Jobs
следующим образом:
Dispatcher.BeginInvoke(new Action((jobs) => populateInbox(jobs)), jobs);
Это связано с тем, что однопараметрическая версия Dispatcher.BeginInvoke
имеет другую подпись в Silverlight, чем в WPF. В Silverlight требуется Action
, что позволяет компилятору С# неявно вводить ваш лямбда как Action
. В WPF он принимает Delegate
(например, его аналог Control.BeginInvoke
в Winforms), поэтому компилятор С# должен явно указывать тип делегата.
Ответ 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