View Full Version : [C#] Problema Multithread
GiulioCesare
18-04-2006, 12:04
Salve ragazzi, ho un problema con la gestione di un multithread. La situazione è la seguente, siccome ho bisogno di fare una query molto grande per avere dei dati, questo blocca per alcuni instanti la grafica della mia applicazione, allora ho pensato di gestire con un altro thread, una label che durante la query, viene visualizzata informando all'utente che l'operazione è in corso. Ma purtroppo quando tento di aggiungere la label al form, mi viene segnalato questo errore: "Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on".
Posto qui di seguito il codice con la speranza che qualcuno possa aiutarmi
public void Metodo1()
{
Thread t;
t = new Thread(newThreadStart(Metodo2));
t.Start();
//Caricamento dati metodo1
t.Abort();
}
public void Metodo2()
{
label.Text = "Caricamento dati in corso";
this.Controls.Add(this.label1);
}
Riordian
18-04-2006, 12:45
perchè usi un thread per fare ciò? Hai bisogno di utilizzare l'applicativo durante il caricamento?
Se ti serve solo per informare l'utente penso che non sia necessario usarlo.
io cambiavo il puntatore del mouse e lo facevo diventare clessidra fino a che non finivo il caricamento (questo in visualc). Puoi fare una cosa simile anche te senza usare un thread. ;)
Io farei una label con il testo che ti serve, la setti visible prima di iniziare il caricamente e poi invisible una volta finito, cmq penso che il tuo problema dipenda dal fatto che il secondo thread cerca di accedere a qualche cosa che è utilizzata dal primo.
Nel multithread l'interazione tra i vari thread deve essere gestita in maniera molto accurata ;)
GiulioCesare
18-04-2006, 13:10
Se uso tutto nello stesso thread, succede quello che ho detto prima.
Ovvero la form si blocca, e tutti i suoi vari componenti non vengono visualizzati :confused:
Riordian
18-04-2006, 13:33
Se uso tutto nello stesso thread, succede quello che ho detto prima.
Ovvero la form si blocca, e tutti i suoi vari componenti non vengono visualizzati :confused:
Mmhh Penso che se la label la fai apparire prima dell'inizio del caricamento Ok che la form si blocca però l'utente dovrebbe riuscire a vederla, cmq non puoi cambiare il puntatore del mouse e fare apparire una clessidra mentre stai caricando? Oltretutto è il comportamento standard di Windows.
Non se che suggerirti sui thread perchè con c# non ho ancora avuto il piacere di utilizzarli, quindi non conosco i metodi che le varie classi offrono, cmq io cercherei una soluzione alternativa.
Tra l'altro ho provato proprio in questo momento ad inserire una labal e mi funziona correttamente senza usare il multithread.
GiulioCesare
18-04-2006, 13:44
Il problema è che andando tutta l'applicazione del form in stato di stallo, tutti i suoi componenti non vengono visualizzati.
Per quanto riguarda mettere il puntatore come clessidra, potrebbe essere un'idea ma non rende molto intuitivo, che l'applicazione sta lavorando :(
Riordian
18-04-2006, 13:51
Il problema è che andando tutta l'applicazione del form in stato di stallo, tutti i suoi componenti non vengono visualizzati.
Boh, da me si comporta in maniera diversa, forse perchè il tempo di load è minimo, si comporta così quando debaggo ma in release no.
Per quanto riguarda mettere il puntatore come clessidra, potrebbe essere un'idea ma non rende molto intuitivo, che l'applicazione sta lavorando :(
Su questo non sono molto d'accordo, se l'applicativo è sotto Windows secondo me è la cosa più intuitiva che ci sia.
GiulioCesare
18-04-2006, 14:51
Sul fatto che il form si blocchi, penso che dipenda proprio dalla pesantezza del mio metodo.
Per quanto riguarda il puntatore trasformato in clessidra, purtroppo queste scelte non dipendono da me :(
Einstein
18-04-2006, 14:55
Prova così (lo faccio al volo, quindi non sarà completamente affidabile... :)):
private void ShowMessageStatus(string message)
{
lblMessage.Text = message;
}
private void LoadData()
{
ShowMessageStatusDelegate showMsg = new ShowMessageStatusDelegate(ShowMessageStatus);
this.Invoke(showMsg, new object[] {"Inizio caricamento dati..."});
// algoritmo di caricamento dati
this.Invoke(showMsg, new object[] {"Fine caricamento dati..."})
}
private delegate void LoadDataDelegate();
private delegate void ShowMessageStatusDelegate(string message);
private void Metodo1()
{
LoadDataDelegate myWorker = new LoadDataDelegate(LoadData);
myWorker.BeginInvoke(null, null);
}
E' sicuramente migliorabile, ma potrebbe essere un inizio.
Ti consiglio anche di dare un'occhiata a questo ottimo articolo sull'argomento: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnforms/html/winforms06112002.asp
Ciao
GiulioCesare
18-04-2006, 17:39
Purtroppo anche gestendo un altro thread in questa maniera, il problema rimane. Quando la query è in esecuzione, ogni thread che parte da questa applicazione va in stato di stallo, e quindi tutti i suoi oggetti non vengono visualizzati, compresa anche la freccia del mouse, che in quel momento risulta bloccata. Possibile che non ci sia modo per gestire questa cosa? :mc:
Einstein
18-04-2006, 20:44
L'accesso ai dati (quello che nel mio esempio è la funzione LoadData()) deve avvenire nel thread secondario, quindi non dovresti avere problemi di stallo dell'applicazione. E' molto strano...
Se usi il .NET Framework 2.0, potresti anche utilizzare gli asynchronous commands di ADO.NET, di cui puoi trovare un esempio qui:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/async2.asp
Ciao
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.