2011-06-13 28 views
6

Il richiamo di un thread dell'interfaccia utente da un thread di lavoro viene discusso molte volte e sappiamo perché utilizzare BeginInvoke() anziché Invoke(). Recentemente ho pubblicato this question e dopo aver fatto qualche ricerca ho scoperto che ci sono almeno tre modi diversi (internamente potrebbero essere uguali) per invocare (in modo asincrono) qualcosa sul thread dell'interfaccia utente.control.BeginInvoke() Vs Dispatcher Vs SynchronizationContext Vs .. - AFFIDABILITÀ

  1. Control.BeginInvoke()
  2. Utilizzando SynchronizatoinContext Classe
  3. Utilizzando Dispatcher.BeginInvoke(priority..)

qualcuno può dirmi che è un modo affidabile per chiamare in modo asincrono un metodo per essere eseguito su thread dell'interfaccia utente. Qualche esperienza? Vedo che Dispatcher.BeginInvoke ha una componente prioritaria, lo rende più affidabile?

Contesto:
stiamo usando someControl.BeginInvoke() ma ho notato che a volte (purtroppo solo in ambiente di produzione all'utente finale) il delegato passò a BeginInvoke is mai eseguito che mi fa credere che il messaggio dopo che si crea è perdersi. Vogliamo un modo affidabile per comunicare al thread dell'interfaccia utente. control.Invoke() a volte si blocca l'interfaccia utente, quindi non vogliamo nemmeno andare lì.

+0

Non confondere WinForms con WPF. – SLaks

+0

Sto avendo un problema simile ... per caso hai risolto il problema? –

+0

stesso qui, qualsiasi aggiornamento? – Pedro77

risposta

0

Tutti funzionano come dovrebbero, se si chiama BeginInvoke ea volte non succede nulla, c'è qualche problema nell'ambiente o nel chiamare il codice, probabilmente - non è che BeginInvoke non sia affidabile. Beh, potrebbe esserci un bug, ma è molto meno probabile.

Forse potresti dare più contesto e possiamo aiutarti a diagnosticare.

+0

Grazie per la risposta. Ho uno scenario simile nel nostro codice. http://stackoverflow.com/questions/6270514/control-begininvoke-fails-to-call-the-delegate – karephul

+0

Ciao Karephul, è interessante ma non aiuta molto in questo caso poiché non hanno trovato una risposta . Qual è la tua configurazione di base in termini di thread, processi, blocchi, ecc.? –

+0

Oh ... è lo stesso problema? Ripubblicato qui? –

0

SynchronizationContext è più astratto e adattabile in molti casi. È un involucro di implementazione specifica. MSDN dice "I provider di modelli di sincronizzazione possono estendere questa classe e fornire le proprie implementazioni per questi metodi".

+0

SynchronizationContext è perferred qui: http://social.msdn.microsoft.com/Forums/en-US/async/thread/1218c86e-fa9b-45a6-93b0-5e27616a6c21 – Steel

0

È necessario prestare attenzione con le funzioni lambda e BeginInvoke. Ho avuto un codice come questo che ha provocato ogni sorta di comportamento strano.

MyThing thing; 
while(GetThing(ref thing)) { 
    control.BeginInvoke((Action)(() => control.Text = thing.ToString())); 
} 

Il problema è che thing non viene valutato quando si crea la funzione lambda. Viene valutato quando viene eseguita la funzione lamdba. Ma è legato a una variabile che sta cambiando nello stesso tempo nel thread del produttore.

È possibile risolvere questo problema dichiarando una copia variabile locale di thing

MyThing thing; 
while(GetThing(ref thing)) { 
    MyThing thing_x = thing; 
    control.BeginInvoke((Action)(() => control.Text = thing_x.ToString())); 
} 

Oppure si può mettere la bruttezza BeginInvoke in un involucro

MyThing thing; 
while(GetThing(ref thing)) { 
    SetText(thing); 
} 

void SetText(MyThing thing) 
    control.BeginInvoke((Action)(() => control.Text = thing.ToString())); 
} 
Problemi correlati