Domanda

Ho visto la messa a punto comune per l'accesso filettatura croce a un controllo GUI, come discusso qui: strada più breve per scrivere un metodo di accesso thread-safe a un controllo Windows Form

Tutti i colpi web ho trovato descrivere una cosa simile.

Tuttavia, perché abbiamo bisogno di controllare InvokeRequired? Non possiamo semplicemente chiamare direttamente Invoke?

Suppongo che la risposta è no, quindi la mia vera domanda è 'perché'?

È stato utile?

Soluzione

Da discussioni non-UI non può toccare l'interfaccia utente - cose molto cattive possono accadere, dal momento che i controlli hanno affinità di thread. Quindi, da un thread non-UI dobbiamo (ad un minumum) chiamata Invoke o BeginInvoke.

Per UI-thread, però - abbiamo non desidera chiamare un sacco Invoke di tempo; il problema è che se si è già sul thread UI, ha ancora l'inutile sovraccarico di inviare un messaggio alla pompa del modulo e la trasformazione.

In realtà, nella maggior parte del codice di threading so si aspetta un metodo specifico per essere chiamato su un non filo -ui, così in questi casi, non v'è alcuna ulteriore spese generali:. basta chiamare Invoke

Altri suggerimenti

InvokeRequired fondamentalmente ti dice se stai eseguendo sul filo giusto o no. Se non sei sul filo corretta, è necessario schierare il compito di thread corretto altrimenti non si fa. Da qui la necessità per il controllo.

Il problema è che controlli GUI hanno un requisito che solo codice in esecuzione sullo stesso filo utilizzato per un'istanza del controllo GUI può accedere al controllo GUI. Le ragioni di questo requisito sono legati al modo in cui Windows è progettato. Basti dire, sarebbe molto difficile cambiare questo.

L'InvokeRequired verifica l'identità del thread in esecuzione in corso contro l'identità del thread creare un'istanza. Se sono uguali, il codice può liberamente interagire con il controllo. In caso contrario, il codice deve marshalling i dati attraverso dal thread corrente al filo creare un'istanza. Questo è un processo lento e costoso ed è da evitare se possibile. Il tuo codice funziona se si richiama sempre e può darsi che non si noterà il calo di prestazioni, ma questo scenario sarà sempre più comuni come i sistemi multi-core entrano in uso. E 'meglio non creare codice "nodi" che devono essere annullata in seguito.

Se si tenta di richiamare prima della creazione di un handle di finestra (per esempio, quando si chiama costruttore del form), si otterrà un InvalidOperationException. Quindi, è necessario controllo generalmente InvokeRequired.

MSDN per i dettagli.

Una ragione che posso pensare è Performence. Se la maggior parte delle volte il thread chiamante è lo stesso il filo creazione allora si dovrà certo overhead unnessecry.

L'Invoke chiamerà il codice tramite delegato e non direttamente che sarebbe costoso.

Il suo costo efficace per chiamare Invoke solo quando richiesto. Quindi, InvokeRequired viene utilizzato per scoprire è la chiamata che viene fatta dello stesso filo o altro thread?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top