|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Jan 2009
Messaggi: 609
|
[C#] Gestione dei thread all'interno di un ciclo di "for"
Ciao a tutti! sto avendo un problema a gestire i thread all'interno di un ciclo di "for".
Mi spiego: il mio obiettivo è di avviare un metodo ogni qualvolta il ciclo di "for" avanza di uno step. Però, per evitare che il metodo blocchi l'esecuzione del programma, avevo pensato di avviarlo in un thread separato. In questo modo, ad ogni ciclo di "for" viene creato un thread che avvia il proprio metodo. Però non funziona come vorrei e non sto capendo il perché. Pubblico il codice perché mi possiate aiutare, se potete. Grazie. Codice:
public partial class MyForm: Form
{
(come fa "i" a raggiungere il valore "3" se il limite al ciclo di "for" è "2"? HELP, Please! Thanks so much!
__________________
L'iPad? Potrebbe esserci gente che, pur d'avere il nuovo gadget, si mette a leggere i libri. Questa sì sarebbe una rivoluzione (Beppe Severgnini)
|
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Dec 2003
Messaggi: 4907
|
È un problema di sincronizzazione.
La variabile i viene incrementata dal ciclo for contemporaneamente all'esecuzione dei vari thread. Puoi risolvere passando la variabile come argomento ad un metodo (anonimo e non) in modo da crearne una copia. PS: Usa le collezioni generiche, evita ArrayList come la peste. |
|
|
|
|
|
#3 | |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
Cmq, la risolverei così : Codice:
private ArrayList listOfThreads = new ArrayList();
private void mio_metodo(object I)
{
MessageBox.Show("'i' corrente vale: " + I.ToString());
//...
}
Codice:
for (int i = 0; i < 3; i++)
{
Thread T = new Thread(new ParameterizedThreadStart(mio_metodo));
T.SetApartmentState(ApartmentState.STA);
this.listOfThreads.Add(T);
T.Start(i);
}
|
|
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Jan 2009
Messaggi: 609
|
@||ElChE||88: in parte ho risolto... come hai detto tu...
P.S: perché dovrei evitare le ArrayList? le ho sempre usate, mai un problema, e le trovo molto comode EDIT: @MarcoGG: uhm... ho visto or ora il tuo intervento, ti ringrazio. Ora provo subito la tua soluzione.
__________________
L'iPad? Potrebbe esserci gente che, pur d'avere il nuovo gadget, si mette a leggere i libri. Questa sì sarebbe una rivoluzione (Beppe Severgnini)
Ultima modifica di alex783 : 19-10-2009 alle 21:14. |
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Jan 2009
Messaggi: 609
|
Marco, ho provato la tua soluzione, ma mi dà questo errore:
"Errore 1 Nessun overload per 'mio_metodo' corrispondente al delegato 'System.Threading.ParameterizedThreadStart'" Come mai? Poi, perché nella dichiarazione del metodo mio_metodo hai messo il tipo dato generico object anziché int? è necessario fare questo?
__________________
L'iPad? Potrebbe esserci gente che, pur d'avere il nuovo gadget, si mette a leggere i libri. Questa sì sarebbe una rivoluzione (Beppe Severgnini)
|
|
|
|
|
|
#6 | |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
E' richiesto dal ParameterizedThreadStart. |
|
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Jan 2009
Messaggi: 609
|
ora funziona... però mi sa che così sia possibile passare solo un dato al metodo... se avessi bisogno di passare ad esempio due variabili, mi restituisce l'errore di prima... certo, potrei passare un arraylist che contiene le diverse variabili che mi servono, ma non la trovo molto elegante come soluzione.
Grazie comunque, per ora questa soluzione va benone!
__________________
L'iPad? Potrebbe esserci gente che, pur d'avere il nuovo gadget, si mette a leggere i libri. Questa sì sarebbe una rivoluzione (Beppe Severgnini)
|
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Il perche' stampi sempre 3 con il tuo metodo e' presto detto.
Nonostante tu abbia lanciato ciascuno Thread dentro il ciclo, i Thread partono e processati schedulati quando vuole lo shcedulatore. Il tuo output significa che da ciascuno viene raggiunta l'istruzione MessageBox.Show("'i' corrente vale: "+i.ToString()); quando in realta' il ciclo chiamante e' gia' terminato, ovvero quando la i vale gia' 3. Per come risolvere problemi come questo, ci sono tanti modi. Alcuni eleganti, alcuni efficienti, alcuni preferiti. Relativamente a .net 2.0 / 3.5 puro, per eseguire un metodo piu' volte in maniera asincrona, non e' necessario scomodare i Thread, ma bastano i delegate (che tanto usi comunque per dichiarare il Thread, quindi un passo in meno) Senza scomodare .Net4.0 o 3.5 con le parallel extensions, sotto 3.5 puro lo scrirverei cosi', (sotto 2.0 risulta solo un po' piu' verboso). Codice:
for (int i = 0; i < 3; i++)
{
Action<int> newAct = new Action<int>{ i=> MetodoDaEseguire(i)};
newAct.BeginInvoke(i, null, null);
}
Male forzare ApartmentState, dato che non e' assicurato il risutalto, ora e' deprecata e occorrerebbe usare TrySetApartmentState (che come dice il nome non ne assicura di per se il risultato) Per un compito come questo non userei Thread o ThreadPool, sebbene sia possibile.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
|
|
|
|
|
#9 | |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
Puoi passare una List di Objects e nel Metodo eseguire i cast opportuni. Elegante o meno, è la soluzione giusta per questo tipo di approccio. Altra soluzione è avere l'istanza di una classe che esponga il Metodo. I campi della classe sono i "parametri", e una volta impostati, si lancia il Thread su quel Metodo, senza passare alcun parametro, e senza bisogno di ParameterizedThreadStart. In ogni caso ParameterizedThreadStart è opzionale, in quanto il compilatore è in grado di utilizzarlo da solo, se rileva il passaggio di un argomento. Questo codice funziona ugualmente : Codice:
Thread T = new Thread(mio_metodo);
T.SetApartmentState(ApartmentState.STA);
this.listOfThreads.Add(T);
T.Start(i);
|
|
|
|
|
|
|
#10 | |
|
Senior Member
Iscritto dal: Jan 2009
Messaggi: 609
|
Quote:
L'istruzione MessageBox.Show chiaramente non c'è nel metodo vero e proprio che uso nella mia applicazione, ma è servito a me per capire il comportamente del metodo. Credo che l'uso dei thread sia necessario al mio caso, dal momento che metodoDaEseguire contiene codice per gestire DotNetZip, quindi ho necessità di dare all'utente la possibilità - ad esempio - di sospendere momentaneamente una compressione ZIP. Grazie per la spiegazione del mio problema, ma comunque non capisco come faccia "i" ad assumere il valore "3" se il limite imposto nel ciclo di "for" è 2. Boh, mi sembra incomprensibile...
__________________
L'iPad? Potrebbe esserci gente che, pur d'avere il nuovo gadget, si mette a leggere i libri. Questa sì sarebbe una rivoluzione (Beppe Severgnini)
|
|
|
|
|
|
|
#11 | |
|
Senior Member
Iscritto dal: Jan 2009
Messaggi: 609
|
Quote:
__________________
L'iPad? Potrebbe esserci gente che, pur d'avere il nuovo gadget, si mette a leggere i libri. Questa sì sarebbe una rivoluzione (Beppe Severgnini)
|
|
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Jan 2009
Messaggi: 609
|
mi chiedevo... ma l'eventuale eccezione di cross-thread, potrei risolverlo con i delegati, giusto?
domani mattina provo, ora vado a nanna... grazie a tutti!
__________________
L'iPad? Potrebbe esserci gente che, pur d'avere il nuovo gadget, si mette a leggere i libri. Questa sì sarebbe una rivoluzione (Beppe Severgnini)
|
|
|
|
|
|
#13 | |
|
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Quote:
Codice:
for (int i=0;i<3;i++)
{
//Fai qualunque cosa, volendo anche nulla
}
Console.WriteLine(i);
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
|
|
|
|
|
|
#14 | |
|
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
Quote:
Usa List<Thread> e non te ne pentirai. |
|
|
|
|
|
|
#15 | ||
|
Senior Member
Iscritto dal: Jan 2009
Messaggi: 609
|
Quote:
i=0 --> è minore di 3? si, allora aggiungi +1 i=1 --> è minore di 3? si, allora aggiungi +1 i=2 --> è minore di 3? si, allora aggiungi +1 i=3 --> è minore di 3? no, esci dal ciclo Grazie mille, non ci avevo proprio pensato. Quote:
Grazie!
__________________
L'iPad? Potrebbe esserci gente che, pur d'avere il nuovo gadget, si mette a leggere i libri. Questa sì sarebbe una rivoluzione (Beppe Severgnini)
|
||
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 12:43.










(come fa "i" a raggiungere il valore "3" se il limite al ciclo di "for" è "2"?










