2010-09-21 4 views
37

J'ai essayé de suivre quelques exemples WCF Data Services et ont le code suivant:Dispatcher BeginInvoke Syntaxe

private void OnSaveCompleted(IAsyncResult result) 
    { 
     Dispatcher.BeginInvoke(() => 
     { 
      context.EndSaveChanges(result); 
     }); 
    } 

qui est appelé par ce qui suit:

this.context.BeginSaveChanges(SaveChangesOptions.Batch, this.OnSaveCompleted, null); 

Maintenant, je reçois un peu confus ici. Tout d'abord, le premier bit de code affiche une erreur de syntaxe de "L'expression lambda de type d'argument n'est pas assignable au type de paramètre System.Delegate". Donc, au lieu d'essayer aveuglément de suivre le code d'exemple, j'ai essayé de comprendre ce qui se passait ici. Malheureusement, j'ai du mal à comprendre l'erreur et ce qui se passe réellement. Je me sens un peu stupide car je suis sûr que c'est facile.

Merci d'avance pour toute illumination!

Répondre

79

Le problème est que le compilateur ne sait pas quel genre de délégué vous essayez de convertir l'expression lambda. Vous pouvez résoudre ce problème soit avec un plâtre ou une variable séparée:

private void OnSaveCompleted(IAsyncResult result) 
{   
    Dispatcher.BeginInvoke((Action) (() => 
    { 
     context.EndSaveChanges(result); 
    })); 
} 

ou

private void OnSaveCompleted(IAsyncResult result) 
{ 
    Action action =() => 
    { 
     context.EndSaveChanges(result); 
    }; 
    Dispatcher.BeginInvoke(action); 
} 
+1

Merci, mais maintenant je Je reçois "Impossible d'accéder à la méthode non statique 'BeginInvoke' dans static conte xt. Je suis plus confus maintenant, car ce n'est pas une méthode statique? –

+1

@Jon: Il pense que vous essayez d'utiliser BeginInvoke comme méthode statique sur la classe Dispatcher - alors que vous voulez utiliser la propriété Dispatcher * *, puis appelez BeginInvoke sur l'instance concernée. Ma conjecture est que ce n'est pas dans une classe appropriée avec une propriété Dispatcher. Après avoir vu que c'est WCF, je ne suis pas sûr d'où vous auriez un Dispatcher. Je suis plus habitué à l'utiliser depuis WPF et Silverlight. –

+1

Il s'agit en fait d'une classe ViewModel dans une application WPF –

7

Répondre par Jon Skeet est très bon, mais il y a d'autres possibilités. Je préfère "commencer à invoquer une nouvelle action" qui est facile à lire et à retenir pour moi.

private void OnSaveCompleted(IAsyncResult result) 
{  
    Dispatcher.BeginInvoke(new Action(() => 
    { 
     context.EndSaveChanges(result); 
    })); 
} 

ou

private void OnSaveCompleted(IAsyncResult result) 
{  
    Dispatcher.BeginInvoke(new Action(delegate 
    { 
     context.EndSaveChanges(result); 
    })); 
} 

ou

private void OnSaveCompleted(IAsyncResult result) 
{  
    Dispatcher.BeginInvoke(new Action(() => context.EndSaveChanges(result))); 
} 
+0

peut-être que cela coûte plus cher de faire une "nouvelle action" que de simplement faire (Action)? –

0

Si votre méthode ne nécessite pas de paramètres, c'est la version la plus courte que j'ai trouvé:

Application.Current.Dispatcher.BeginInvoke((Action)MethodName);