Ho uno scenario. (Windows Form, C #, .NET)
- Esiste un modulo principale che ospita alcuni controlli utente.
- Il controllo utente esegue alcune operazioni con dati pesanti, in modo tale che se chiamo direttamente il
UserControl_Load
metodo l'interfaccia utente non risponde per la durata dell'esecuzione del metodo di caricamento. - Per ovviare a questo carico i dati su thread diversi (cercando di modificare il codice esistente il meno possibile)
- Ho usato un thread di lavoro in background che caricherà i dati e quando fatto notifica all'applicazione che ha fatto il suo lavoro.
- Ora è arrivato un vero problema. Tutta l'interfaccia utente (modulo principale e relativi controlli utente secondari) è stata creata sul thread principale principale. Nel metodo LOAD del controllo utente sto recuperando i dati in base ai valori di alcuni controlli (come la casella di testo) su userControl.
Lo pseudocodice sarebbe simile al seguente:
CODICE 1
UserContrl1_LoadDataMethod()
{
if (textbox1.text == "MyName") // This gives exception
{
//Load data corresponding to "MyName".
//Populate a globale variable List<string> which will be binded to grid at some later stage.
}
}
L'eccezione che ha dato è stata
Operazione cross-thread non valida: controllo a cui si accede da un thread diverso dal thread su cui è stato creato.
Per saperne di più ho fatto un po 'di ricerche su Google e un suggerimento è venuto fuori come usare il seguente codice
CODICE 2
UserContrl1_LoadDataMethod()
{
if (InvokeRequired) // Line #1
{
this.Invoke(new MethodInvoker(UserContrl1_LoadDataMethod));
return;
}
if (textbox1.text == "MyName") // Now it wont give an exception
{
//Load data correspondin to "MyName"
//Populate a globale variable List<string> which will be binded to grid at some later stage
}
}
MA MA MA ... sembra che io sia tornato al punto di partenza. L'applicazione diventa nuovamente non rispondente. Sembra essere dovuto all'esecuzione della riga n. 1 se la condizione. L'attività di caricamento viene nuovamente eseguita dal thread principale e non dal terzo che ho generato.
Non so se ho percepito questo giusto o sbagliato. Sono nuovo del threading.
Come posso risolvere questo e anche qual è l'effetto dell'esecuzione della riga n. 1 in caso di blocco?
La situazione è questa : voglio caricare i dati in una variabile globale in base al valore di un controllo. Non voglio cambiare il valore di un controllo dal thread figlio. Non lo farò mai da un thread figlio.
Quindi solo l'accesso al valore in modo che i dati corrispondenti possano essere recuperati dal database.