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