Dispatcher.Invoke с анонимным делегатом работает в Silverlight, но не в WPF - PullRequest
10 голосов
/ 19 июля 2010

В 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 для меня не вариант.

Ответы [ 2 ]

26 голосов
/ 19 июля 2010

Вам необходимо указать явный тип делегата. Просто используйте 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 # неявно печатать вашу лямбду как Action. В WPF требуется Delegate (как и его Control.BeginInvoke аналог в Winforms), поэтому компилятору C # необходимо явно указать тип делегата.

2 голосов
/ 16 апреля 2011

В 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

...