19

I'm having a problem that I can't seem to figure out, although its kind of a standard question here on Stackoverflow.

I'm trying to update my Bing Maps asynchronously using the following code (mind you, this is from an old Silverlight project and does not seem to work in WPF)

_map.Dispatcher.BeginInvoke(() =>
{
    _map.Children.Clear();
    foreach (var projectedPin in pinsToAdd.Where(pin => PointIsVisibleInMap(pin.ScreenLocation, _map)))
    {
        _map.Children.Add(projectedPin.GetElement(ClusterTemplate));
    }
});

What am I doing wrong?

Gericke
  • 2,109
  • 9
  • 42
  • 71
Niels
  • 2,496
  • 5
  • 24
  • 38

3 Answers3

43

You have to cast it explicitly to a Action in order for the conversion to System.Delegate to kick in.

That is:

_map.Dispatcher.BeginInvoke((Action)(() =>
{
    _map.Children.Clear();
    foreach (var projectedPin in pinsToAdd.Where(pin => PointIsVisibleInMap(pin.ScreenLocation, _map)))
    {
        _map.Children.Add(projectedPin.GetElement(ClusterTemplate));
    }
}));
Gericke
  • 2,109
  • 9
  • 42
  • 71
Jean Hominal
  • 16,518
  • 5
  • 56
  • 90
14

The BeginInvoke() method's parameter is the base Delegate class.

You can only convert a lambda expression to a concrete delegate type.

To fix this issue, you need to explicitly construct a delegate:

BeginInvoke(new MethodInvoker(() => { ... }));
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 14
    Little known fact: it is *marginally* more efficient to use `MethodInvoker` here, rather than `Action` / `ThreadStart`, etc - even though the signature is identical: it has direct support in `Control.InvokeMarshaledCallbackDo` (via `is`/cast) - where-as other delegate types use `DynamicInvoke`. The only other directly-supported delegate types are `WaitCallback` and `EventHandler` – Marc Gravell Jan 17 '13 at 14:35
3

Try

Dispatcher.BeginInvoke(new System.Threading.ThreadStart(delegate
{
//Do something
}));

Or use Action

Alex
  • 8,827
  • 3
  • 42
  • 58
  • 5
    For your interest, you might want to see the comment I added to SLaks' answer – Marc Gravell Jan 17 '13 at 14:36
  • http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx: The delegate can be an instance of EventHandler, in which case the sender parameter will contain this control, and the event parameter will contain EventArgs.Empty. The delegate can also be an instance of MethodInvoker, or any other delegate that takes a void parameter list. A call to an EventHandler or MethodInvoker delegate will be faster than a call to another type of delegate. – Alex Jan 17 '13 at 15:14