2013-01-17 15 views
34

Potrebbe spiegare questo per me per favore:Come utilizzare BeginInvoke C#

someformobj.BeginInvoke((Action)(() => 
{ 
    someformobj.listBox1.SelectedIndex = 0; 
})); 

Potrebbe dirmi come posso utilizzare begininvoke esattamente? Che cos'è il tipo Action? Perché ci sono parentesi vuote ()? E cosa vuol dire =>?

+2

tante domande diverse in un solo post ... - ci dovrebbero essere almeno 3 domande separate – Prokurors

+0

Dai un'occhiata anche a questo articolo http://mark-dot-net.blogspot.com.uy/2014/07 /six-ways-to-initiate-tasks-on-another.html –

risposta

57

Action è un tipo di delegato fornito dal framework .NET. Il Action punta a un metodo senza parametri e non restituisce un valore.

() => è la sintassi lambda expression. Le espressioni lambda non sono di tipo Delegate. Invoke richiede Delegate così Action può essere usato per avvolgere l'espressione lambda e fornire l'atteso Type di Invoke()

Invoke cause detti Action per eseguire sul thread che ha creato handle di finestra del controllo. La modifica dei thread è spesso necessaria per evitare Exceptions. Ad esempio, se si tenta di impostare la proprietà Rtf su un RichTextBox quando è necessario un Invoke, senza prima chiamare Invoke, verrà generata un'eccezione Cross-thread operation not valid. Controlla Control.InvokeRequired prima di chiamare Invoke.

BeginInvoke è la versione asincrona di Invoke.Asincrono significa che il thread non bloccherà il chiamante al contrario di una chiamata sincrona che sta bloccando.

+0

Grazie mille :) –

+0

Quindi, se ho capito bene, Action è usato per garantire la sicurezza cross-thread, quindi informeresti l'oggetto tramite la chiamata al metodo invece di impostare tu stesso il valore? Inoltre, il metodo accetterà QUALSIASI delegato, non solo un'azione in particolare, sì? –

+4

@KyleBaran - 'Action' non è correlato alla sicurezza dei thread, ovvero' Invoke'. 'Invoke' accetta un' delegato' come parametro. Quindi qualsiasi cosa convertibile in un 'Delegato 'può essere passato come parametro. –

9

Immagino che il vostro codice si riferisca a Windows Form.
Si chiama BeginInvoke se è necessario eseguire qualcosa in modo asincrono nel thread dell'interfaccia utente: modificare le proprietà del controllo nella maggior parte dei casi.
In parole povere questo è possibile passare il delegato ad una procedura che viene eseguita periodicamente. (elaborazione del loop di messaggi e cose del genere)

Se BeginInvoke è chiamato per il tipo Delegate, il delegato viene richiamato in modo asincrono.
(Invoke per la versione di sincronizzazione.)

Se vuoi codice più universale, che funziona perfettamente per WPF e WinForms si può considerare Task Parallel Library e l'esecuzione del Task con il secondo context. (TaskScheduler.FromCurrentSynchronizationContext())

E per aggiungere un po 'di già detto da altri: lambda possono essere trattati sia come metodi anonimi o expressions.
E questo è il motivo per cui non puoi semplicemente usare var con lambdas: il compilatore ha bisogno di un suggerimento.

UPDATE:

questo richiede .Net V4.0

// This line must be called in UI thread to get correct scheduler 
var scheduler = System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext(); 

// this can be called anywhere 
var task = new System.Threading.Tasks.Task(() => someformobj.listBox1.SelectedIndex = 0); 

// also can be called anywhere. Task will be scheduled for execution. 
// And *IF I'm not mistaken* can be (or even will be executed synchronously) 
// if this call is made from GUI thread. (to be checked) 
task.Start(scheduler); 

Se hai iniziato l'attività da altro thread e la necessità di attendere per la sua completition task.Wait() bloccherà chiamando filo fino la fine del compito.

Maggiori informazioni sulle attività here.

+0

potresti darmi qualche esempio per favore? –

+0

@MohammedNoureldin Ho aggiunto un po 'di codice –