2010-09-21 12 views
37

ho cercato di seguire alcuni esempi WCF Data Services e hanno il seguente codice:Dispatcher BeginInvoke Sintassi

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

che è chiamato dal seguente:

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

Ora mi stanno un po ' confuso qui. Innanzitutto, il primo bit di codice mostra un errore di sintassi di "Argument type lambda expression non è assegnabile al tipo di parametro System.Delegate". Quindi, invece di cercare ciecamente di seguire il codice di esempio, ho cercato di capire cosa stava succedendo qui. Sfortunatamente sto lottando per capire l'errore più ciò che sta realmente accadendo.

Mi sento un po 'stupido perché sono sicuro che sia facile.

Grazie in anticipo per qualsiasi chiarimento!

risposta

79

Il problema è che il compilatore non sa che tipo di delegato si sta tentando di convertire l'espressione lambda in. È possibile risolvere che o con un cast, o di una variabile indipendente:

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

Grazie, ma ora sto ottenendo "Impossibile accedere al metodo non statico" BeginInvoke "in conte statico xt. Sono più confuso ora, in quanto questo non è un metodo statico? –

+1

@Jon: pensa che tu stia cercando di utilizzare BeginInvoke come metodo statico sulla classe Dispatcher, mentre si desidera utilizzare la proprietà Dispatcher * e quindi chiamare BeginInvoke sull'istanza pertinente. La mia ipotesi è che questo non è in una classe appropriata con una proprietà Dispatcher. Avendo appena visto che questo è WCF, non sono sicuro di dove si possa ottenere un Dispatcher. Sono più abituato ad usarlo da WPF e Silverlight. –

+1

Questo è in realtà su una classe ViewModel in un'applicazione WPF –

7

risposta da Jon Skeet è molto buona, ma ci sono altre possibilità. Preferisco "iniziare a invocare nuove azioni", che è facile da leggere e da ricordare per me.

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

forse costa di più fare una "nuova azione" rispetto al cast (azione) appena fatto? –

0

Se il metodo non richiede parametri, questa è la versione più breve che ho trovato:

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