OK.
Haj'mo redom.
1.
Tako je......Ostavio sam metodu svasta(...) da ti pokazem na koji nacin bi se ona mogla pozivati u konkretnom kodu a da se ne "sudara" sa drugim threadovima i da kod ispravno radi. Tu metodu bi trebalo prihvatiti kao "los" nacin za postizanje zeljenog rezultata. Sto znaci, treba je promijeniti ili potpuno izbaciti. Ako bi je izbacili, onda moramo naci druga+tehnicki ispravna logicka rjesenja za dati problem a to sada zavisi od tebe(programera) da nadjes odgovarajuci nacin.
Sa tehnicke strane postoje razliciti nacini da se neko koristenje Thread-a ucini da bude thread safe. I to je upravo ovo o cemu prica ovaj primjer na MSDN-u koji si poslao. Oni su takodjer upotrijebili 2 nacina da urade istu stvar. Jedan nacin je pomocu novog Thread-a a drugi pomocu background worker-a. I jedan i drugi nacin mogu djelovati sami za sebe tj. nisu zavisni. Ovaj sto se radi preko novog Thread-a se upravo "naslanja" na ono pravilo da sve sto je napravljeno naslijedjivanjem iz ...Control klase ima samo 4 thread-safe metode i jedan property. Dok se za backgroundWorker moze reci, opet uz dosta pjesnicke slobode :), da takvo pravilo "zna-sam-po-sebi" i da ga u svom radu primjenjuje. Ako pogledas backgroundWorker vidjeces da on daje 3 eventa i 2(ovoj prici bitna, a ima ih jos) property-ja. Da bi osposobio da rade sva 3 eventa property "WorkerReportsProgress" mora biti postavljen na "true". Sta se tada desava: Sav posao se obavlja na relaciji prvi event - drugi event. Sto znaci, pokrenes svoj backgroundWorker a on pokrece 1. event. Tu ti primjenjujes neku svoju logiku.....Ali pazljivo jer sve sto ovdje mozes da radis mora biti thread-safe jer se ovaj posao odvija na drugom Thread-u. Znaci, ako u ovom threadu koristis bilo koju kontrolu ili bilo sta sto naslijedjuje iz control klase a koja nije napravljena na ovom threadu dobices thread bug.Da bi ovo sprijecio imas na raspolaganju 2.Event koji pokreces naredbom bakgroundWorker.ReportProgress(...). To je event gdje se sve odvija na threadu koji je napravio backgroundWorker-a a u nasem slucaju i sve kotrole. Znaci, u ovom eventu je sasvim "legalno" mijenjati kontrole tj. Update-ovati progressbar,grid, textBox itd....bilo sta. Ovaj postupak(1-2) se odvija stalno dok god backgroundWorker thread ne zavrsi posao tj. u nasem slucaj dok traje "while.." petlja. Zatim, worker thread javlja da je zavrsio posao a tebi kao korisniku to daje do znanja u 3.Eventu i tu se proces zavrsava. Takodjer, 3.Event se odvija na istom thread-u gdje su u nasem slucaju i sve kontrole pa sta god radio sa nasim kontrolama u ovom eventu je thread-safe. Ovaj drugi property ti omogucava da prekines posao backgroundWorker-thread-a i tada bi posao presao iz 1. eventa u 3.event uz eventualni prolazak kroz event 2 i tu bi bio kraj rada thread-a.
Samo radi pojasnjenja:
1.Event je "backgroundWorker1_DoWork(.....)"
2.Event je "backgroundWorker1_ProgressChanged(...)"
3.Event je "backgroundWorker1_RunWorkerCompleted(...)"
2.
Evo jedan link koji odlicno objasnjava kako rade Invoke(...) i BeginInvoke(...) pa probaj naci vezu izmedju njega i backgroudWorker-a. Poslije njega bi stvari trebale biti jasnije. Thread.Sleep(...) u kodu je samo radi pokaza laganog punjenja grida ti se slobodno mozes rijesiti toga ili prilagodjavati svojim zahtjevima.
http://www.codeproject.com/csharp/begininvoke.asp
3.
Progressbar prilagodjavaj po svojoj zelji - glavna stvar je da ga "punis" na ispravnom thread-u a implementaciju mozes prilagodjavati kako zelis. Izazovi "punjenja" progressbar-a su stalni i naici ces na razlicita rjesenja u praxi (Timer-i,Thread-ovi,sekvence,....itd).
Oko thread-ova ima jos dosta toga sto se veze za implemetaciju ovih gore stvari ali to bi sada na ovoliko detalja bilo i previse. Izvinjavam se ako je post predugacak ali nadam se da ce ti neke stvari, ako nista drugo onda, malo pribliziti i da ga nije bilo naporno citati.
[Ovu poruku je menjao ebug dana 30.06.2006. u 20:51 GMT+1]