2010-07-19 8 views
10

In Silverlight 4 ho una classe di servizio personalizzata che ha un evento Completato asincrono. All'interno della manifestazione Completato prendo i dati restituiti e invocare un metodo popolano via qualcosa di simile:Dispatcher.Invoke con delegato anonimo funziona in Silverlight ma non WPF

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

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

Le BeginInvoke opere in SL4, tuttavia quando ho portato a WPF ottengo il seguente errore:

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

ho provato a cambiarlo con un filtro in linea, anonima, delegato parametrizzato:

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

tuttavia, che produce lo stesso errore in fase di compilazione.

Qualche idea su come farlo funzionare in WPF? Refactoring per utilizzare il BackgroundWorker non è un'opzione per me.

risposta

26

È necessario specificare un tipo di delegato esplicito. Basta usare un Action.

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

Si potrebbe, tuttavia, evitare di dover chiudere sopra il valore args.Jobs in questo modo:

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

Questo perché la versione a singolo parametro di Dispatcher.BeginInvoke ha una firma diversa in Silverlight che in WPF. In Silverlight, ci vuole uno Action, che consente al compilatore C# di digitare implicitamente il tuo lambda come Action. In WPF, prende uno Delegate (come il suo analogo Control.BeginInvoke in Winforms), quindi il compilatore C# deve avere un tipo di delegato esplicitamente specificato.

+0

sto ottenendo questo errore ora: è necessario un riferimento a un oggetto per il campo non statico, metodo o proprietà 'System.Windows.Threading.Dispatcher.BeginInvoke (System.Delegate, params object []) '. L'ho separato in 2 righe per provare a vedere che cosa causa l'errore. var d = new Action (() => populateInbox (args.Jobs)); Dispatcher.BeginInvoke (d, args.Jobs); L'errore si verifica sulla seconda riga. –

+0

Dispatcher.BeginInvoke (d, nuovo oggetto [] {args.Jobs}); Non funziona neanche. –

+1

@Edward: 'Dispatcher' non è una classe statica. Dovrai chiamare questa funzione nel contesto di un elemento dell'interfaccia utente che ha una proprietà 'Dispatcher', o dovrai passare nel dispatcher come un altro argomento. –

2

In WPF e winforms è necessario prima convertirlo in un MethodInvoker, altrimenti si otterrà l'errore Impossibile convertire il metodo anonimo per digitare "System.Delegate" perché non è un tipo delegato.

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

Per maggiori informazioni: http://msdn.microsoft.com/en-us/library/system.windows.forms.methodinvoker.aspx