Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dispatcher.Invoke with anonymous delegate works in Silverlight but not WPF

In Silverlight 4 I have a custom service class which has an asynchronous Completed event. Inside the Completed event I take the returned data and invoke a populate method via something like this:

private void service_Completed(object sender, CompletedEventArgs args)
{
    Dispatcher.BeginInvoke(() => populateInbox(args.Jobs));
}

private void populateInbox(List<JobViewModel> jobs)
{
    inbox.DataContext = jobs;
}

The BeginInvoke works in SL4, however when I ported it to WPF I get the following error:

Cannot convert lambda expression to type 'System.Delegate' because it is not a delegate type

I tried changing it to an in-line, anonymous, paramaterized delegate:

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

However, that yields the same compile-time error.

Any idea how to get this to work in WPF? Refactoring to use the BackgroundWorker is not an option for me.

like image 988
Edward J. Stembler Avatar asked Jul 19 '10 19:07

Edward J. Stembler


2 Answers

You need to specify an explicit delegate type. Just use an Action.

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

You could, however, avoid having to close over the args.Jobs value like this:

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

This is because the single-parameter version of Dispatcher.BeginInvoke has a different signature in Silverlight than in WPF. In Silverlight, it takes an Action, which allows the C# compiler to implicitly type your lambda as an Action. In WPF, it takes a Delegate (like its Control.BeginInvoke analog in Winforms), so the C# compiler has to have a delegate type explicitly specified.

like image 93
Adam Robinson Avatar answered Nov 15 '22 21:11

Adam Robinson


In WPF and winforms you must cast it to a MethodInvoker first, otherwise you will get the error Cannot convert anonymous method to type 'System.Delegate' because it is not a delegate type.

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

For more info: http://msdn.microsoft.com/en-us/library/system.windows.forms.methodinvoker.aspx

like image 44
Snives Avatar answered Nov 15 '22 21:11

Snives