2010-09-21 11 views
37

he estado tratando de seguir algunos ejemplos de WCF Data Services y tienen el siguiente código:Dispatcher BeginInvoke Sintaxis

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

que es llamada por el siguiente:

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

Ahora me estoy haciendo un poco confundido aquí. En primer lugar, el primer bit de código muestra un error de sintaxis de "Argument type lambda expression no se puede asignar al parámetro type System.Delegate". Entonces, en lugar de intentar ciegamente seguir el código de ejemplo, traté de entender qué estaba pasando aquí. Lamentablemente, estoy luchando por comprender el error y lo que realmente está sucediendo.

Me siento un poco estúpido ya que estoy seguro de que esto es fácil.

¡Gracias de antemano por cualquier aclaración!

Respuesta

79

El problema es que el compilador no sabe a qué tipo de delegado está intentando convertir la expresión lambda. Puede fijar que, o bien con un yeso o una variable independiente:

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

o

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

Gracias, pero ahora estoy recibiendo "No se puede acceder al método no estático 'BeginInvoke' en contestático xt. Estoy más confundido ahora, ya que este no es un método estático? –

+1

@Jon: cree que está intentando utilizar BeginInvoke como método estático en la clase Dispatcher, mientras que desea utilizar la propiedad Dispatcher * y luego llamar a BeginInvoke en la instancia correspondiente. Supongo que esto no está en una clase apropiada con una propiedad de Dispatcher. Después de haber visto que esto es WCF, no estoy seguro de dónde obtendría un Dispatcher. Estoy más acostumbrado a usarlo de WPF y Silverlight. –

+1

Esto es en realidad en una clase de ViewModel en una aplicación de WPF –

7

respuesta por Jon Skeet es muy buena, pero hay otras posibilidades. Prefiero "comenzar a invocar nuevas acciones", que es fácil de leer y recordar para mí.

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

o

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

o

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

, tal vez cueste más hacer una "nueva acción" en comparación con el solo molde (Acción)? –

0

Si el método no requiere parámetros, esta es la versión más corta que encontré:

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