Šta je novo?

Cross-linking i delegat problem

The pocetnik

Čuven
Učlanjen(a)
05.12.2000
Poruke
1,740
Poena
649
Ovako:
Radi lepseg prikaza dodao sam prikaz progressbara u aplikaciju tako sto sam kreirao novu formu samo sa progressbarom sa public metodama tako da iz druge forme mogu lako da im pristupim.Na ovaj nacin progressbar lepo radi sve dok se na isti ne pomeri i onda se na njemu nista ne menja dok se posao ne zavrsi.Da bi resio ovaj problem uveo sam threadove i dosao do cross-linking problema kojeg sam "resio" uz pomoc delegata i Invoke f-je, ali sada prikaz progresbara ne radi tj. samo se pojavi forma i umesto progressbara stoji beli pravougaonik.

Koristio sam sledeci kod u formi2 (forma3 mi je mesto gde se nalazi progressbar)
Kod:
//Form2 kod

Form3 f3;
public Thread t;
bool kraj = false;
int procenat = 0;

public delegate void progressbardelegate();

public void obradaprogresat()
{
	while(!kraj)
	{	
		obradaprogresa1();
	}	
}

public void obradaprogresa1()
{
	if (f3.progressBar1.InvokeRequired)
	{
		progressbardelegate pbg = new progressbardelegate(obradaprogresa1);
		this.Invoke(pbg, new object[] {} );
	}
	else
	{
		f3.progressBar1.Value = procenat;
		f3.progressBar1.Refresh();
	}
}

public void radnafunkcija()
{
	kraj = false;
	procenat = 0;
	f3 = new Form3();
	f3.Show();
	this.Hide();
	t = new Thread(obradaprogresat);
	t.Start();
	
	//ovde funkcija nesto radi i izracunava procenat
	
	kraj = true; //zavrsavam thread t
	f3.Close();
	this.Show();
}

Znaci probao sam i da delegat stavim u formu 3 i da metodu obradaprogresa1 isto stavim u formu 3 i da iz forme 2 pozivam istu i prosledjujem procenat, ali i tako ne radi(isto se javlja beli pravougaonik kao i kada se zavrsi rad javi mi gresku da je objeka Form3 disposed sto radim i na kraju koda u radojfunkciji).Takodje sam cak i dodao pauze u obradaprogresat misleci da mi se stalnim pozivanjem obradaprogresa1 bez pauze desava ovo sa belom bojom, ali ni to nije resenje.

Znam da ovo nije primer lepog programiranja, ali za moje potrebe bolje mi ni ne treba.Gde gresim, tj. sta bi trebalo da dodam u ovaj kod da bi isti prikazivao progressbar koji se nece "gubiti" kada isti pomerim isl?
 
Poslednja izmena:
Imao sam sličan problem i uspeo sam da ga rešim tako što sam progress bar napravio kao posebnu aplikaciju, koju po potrebi startujem i stopiram.
 
A zasto posao koji treba da obavis ne prebacis u neki worker thread a odatle preko Invoke-a obavestavas progress formu o stanju (tj. okidas delegat koji ce da updejtuje progress)?
 
Mozda bi mogao tako da odradim posao, samo da pronadjem primere za to.Mada imam toliko funkcija koje pozivaju progressbar tako da bi se najverovatnije i izgubio u gomili threadova.Ovako sve radim iz sistemskog i uvek pozivam isti thread t.Mislim tako mi je daleko lakse za rad kada vec imam sve te funkcije, da radim ispocetka sigurno bi gledao da kod napisem valjanije tj. u skladu sa pravilima objektno-orjentisanog programiranja.

BTW Sada sam radi probe dodao brojac u else granu obradaprogresa1 da bi video da li se uopste poziva namestanje vrednosti progressbara i dobio sam 0 tj. kao da ovaj moj kod uopste ne radi kako bi trebalo.Zato sumnjam da je svo vreme problem u delegatu tj. da primer prema kojem sam odradio konstrukciju istog kao da nije valjan.
 
Poslednja izmena:
Ma veoma je jednostavno... Imas dosta primera u MSDN-u i po internetu (npr. www.codeproject.com).

Generalno.. nije dozvoljeno dirati UI elemente (prozore i kontrole u njima) iz drugih threadova. Ako imas neke duge operacije, da se UI ne bi blokirao, pokreni taj posao u novom threadu a povremeno obavesti glavni UI thread o progresu. To se radi pomocu Invoke ili BeginInvoke.
 
Workerthread kao sto mu ime kaze je zaduzen za odradjivanje background zadataka.
Zbog toga nije lijepo i dobro kontrolisati GUI elemente iz workerthreada.

Normalno i imas samo pristup na gui-elemente koje si i kreirao u odgovarajucem threadu.

Ako koristis shared podatke izmedju worker i gui threada treba obratiti paznju da bude sinhronizovan pristup istim putem crytical_section ili semafora.
 
Poslednja izmena:
Vrh Dno