Questa è stata una sfortunata scelta di denominazione in .NET. I metodi Control.BeginInvoke e Dispatcher.BeginInvoke hanno lo stesso nome dei metodi di un delegato ma operano completamente diversi. Le differenze principali: type-safe
metodo BeginInvoke() di un delegato è sempre, ha gli stessi argomenti esatte come la dichiarazione delegato. Questo manca completamente dalle versioni Control/Dispatcher, gli argomenti sono passati attraverso una matrice params di tipo oggetto []. Il compilatore non ti dirà quando ottieni una discussione sbagliata, bombarda in fase di esecuzione
Un metodo Invoke() di un delegato esegue la destinazione delegata sullo stesso thread. Non è il caso per Control/Dispatcher.Invoke(), effettua il marshalling della chiamata al thread dell'interfaccia utente
Un'eccezione che viene lanciata nella destinazione BeginInvoke() di un delegato viene catturata e non causa il fallimento del programma. Da ri-generare quando si chiama EndInvoke(). Questo non è assolutamente il caso per Control/Dispatcher.BeginInvoke(), che genera l'eccezione sul thread dell'interfaccia utente. Senza un modo decente di rilevare l'eccezione, uno dei motivi più importanti dell'esistenza di Application.UnhandledException.
Chiamare il metodo EndInvoke() di un delegato è richiesto, causa una perdita di risorse di 10 minuti se non lo si fa. È non necessario per i metodi Control/Dispatcher.BeginInvoke() e in pratica non lo si fa mai.
Utilizzo di Control/Dispatcher.Invoke() è rischioso, è abbastanza probabile che causi stallo. Attivato quando il thread dell'interfaccia utente non è pronto per richiamare il target e fa qualcosa di poco saggio come in attesa del completamento di un thread. Non è un problema per un delegato, non perché il suo metodo Invoke() non usa un thread.
Calling Control/Dispatcher.BeginInvoke() sul thread UI è uno scenario supportato. La destinazione viene ancora eseguita sul thread dell'interfaccia utente, come previsto. Ma più tardi, dopo che il thread dell'interfaccia utente torna di nuovo inattivo e rientra nel ciclo del dispatcher. Questa è in realtà una funzionalità molto utile, aiuta a risolvere problemi di rientro. In particolare nei gestori di eventi per i controlli dell'interfaccia utente che si comportano male quando si esegue il codice con troppi effetti collaterali.
Una grande lista con dettagli di implementazione pesanti. La versione TLDR è certamente: "Non hanno nulla in comune, non chiamare EndInvoke è soddisfacente e del tutto normale".
fonte
2013-08-02 14:31:12
Ottima risposta! La lista di confronto tra 'Control. ... Invoke' e' TDelegate. ... Invoke' dovrebbe essere su MSDN. - Ti suggerisco solo di spiegare su 'Dispatcher' di WPF/Silverlight in una nota a margine, poiché non esiste in Windows Form (che è il contesto di questa domanda). – stakx
Grazie per questo - Ho passato a Control.cs chiedendo come risolvere una coda null: threadCallBackList. Ora posso riposare facilmente e rimuovere EndInvoke che causa il problema! :) –