» »

c# ... kako je to mozno da Windows.Forms.Timer na istem threadu vec msg boxov pozene

c# ... kako je to mozno da Windows.Forms.Timer na istem threadu vec msg boxov pozene

Vapo1 ::

povlecite v Form1 iz toolboxa "Timer" (isto kot ko button ali pa lable potegnete na okno)... naredil se bo timer1

v timer1 properties date enabled da se bo timer startal ko se pozene program.... tudi interval dajte na 3000(3 sekunde) da ne bo poplave msg boxov

dvoklik na timer1 generira funkcijo (na zacetku je prazna - notr dajte kodo kot v spodnji funkciji)

private void timer1_Tick_(object sender, EventArgs e)
{
MessageBox.Show("Msgbox running on threadID: " + Thread.CurrentThread.ManagedThreadId.ToString());
}

in pozenite...


V CEM JE FORA:

timer potem ustvarja nove msg boxe enega za drugim na doloceni periodi... vsi msg boxi so na istem threadu... ko se pojavljajo msg boxi se da upravljati samo ta zadnjega ki se je pojavil.. tudi glavnega forma se ne da upravljati in vsi msgboxi in tudi glavni form so na istem threadu(vsi javijo isti thread ID)...

kako je to mogoce da se na istem threadu pozene vec msg boxov.... kolkor jaz vem naj bi thread zablokiral dokler je msg box prikazan... sele ko kliknes ok na msg boxu gre thread naprej...

mogoce kdo od vas ve kaksna fora se skirva zadaj?

darkolord ::

Ja, zadeva se kliče code "re-entrance" - koda ponovno vstopi v dogodek.

Primer z MessageBoxi ni tako očiten, gre pa za isto zadevo:
- postaviš gumb na formo
- v metodo/dogodek od gumba postaviš eno neskončno zanko, ki prišteva eno spremenljivko in jo nekam izpisuje, na koncu vsakega loopa pa pokličeš Application.DoEvents(), da se forma "osveži"
- ko zadevo zaženeš, opaziš, da lahko gumb klikneš večkrat, prejšnji loop/zanka pa se s tem prekine.

Kaj se zgodi? Application.DoEvents sprocesira vsa sporočila (windows messages), ki čakajo na procesiranje - efekt je ta, da se forma ponovno izriše in ne izgleda zamrznjena. Trik je pa v tem, da se sprožijo tudi vsi eventi zaradi teh sporočil (npr. ko klikneš na gumb).

V tvojem primeru se to zgodi zaradi tega, ker MessageBox.Show ne ustavi procesiranja windows messageov (drugače ne bi mogel klikniti nanjga oz bi bil "zamrznjen"), Timer pa iz drugega threada prek windows messageov sproža evente, ki se sprocesirajo.

To lahko rešiš tako, da uporabiš drug Timer (iz namespacea System.Threading ali System.Timers) ali še enostavneje, timer izklopiš na začetku funkcije in ponovno vklopiš na koncu.

Upam da je razumljivo.

Vapo1 ::

WOW !!!... darko češarko

super odgovor !!

točno to me je zanimalo... teorija delovanja ki se zadaj skriva ... tale fora z Application.DoEvents je huda... zdaj koncno vem kako osvezevati GUI brez da delam nove threade!!!

hvala ti za tole pomembno novo lego kocko v mojem c# arzenalu

darkolord ::

V izogib tem težavam ti za sámo osveževanje sicer raje priporočam metodo Control.Refresh(), ki ponovno izriše celotno kontrolo mimo ostalih čakajočih sporočil, tako da se dejansko res osveži samo kontrola. Gumbov tako ne moreš klikat, je pa vsebina vseeno osvežena.

Če pa vseeno uporabiš Application.DoEvents, moraš nekako preprečiti, da bi uporabnik lahko isto zadevo nenamenoma večkrat zagnal (najlažje tako, da med procesiranjem onemogočiš gumbe oz. ustrezne kontrole)

Vapo1 ::

ce koga zanima tale koda lepo pokaze delovanje (kako se prejsnji loop ustavi in se novi loop zacne.. in vsi prejsnji loopi cakajo)


nareidte button...(in naj bo velik ker mora veliko texta displajat)... in tole vrzite v form1 class: (in potem poklikavajte po gumbu in malo menjajte tempo..)

int i = 0;
int index = 0;
int[] array = new int[100];
private void button1_Click(object sender, EventArgs e)
{
int myInd = index;
index++;
for (int x = 0; x < 10; x++)
{
array[myInd] = x;
i++;
Thread.Sleep(100);
//button1.Text = i.ToString()+"\nrun "+str;
button1.Text = "";
for (int z = 0; z < 20; z++)
{
button1.Text += "\nrun " + " " + array[z].ToString();
}
Application.DoEvents();
}
}

Zgodovina sprememb…

  • spremenilo: Vapo1 ()

Vapo1 ::

hej darko..... sem se se malo igral....

v sredino v loop dam button1.Refresh();

in vsi loopi se lepo po vrsti odvijejo... ampak zanimivo je to da lahko na gumb vseeno veckrat kliknem (ceprav animacija klika (ko se vdolbi in izdolbi gumb) se odvrti samo prvic)... med loopom prvm ko se izvaja klikam po gumbu in si stvar zapomne kolkokrat sem kliknil gor in se izvedejo potem se vsi preostali loopi eden za drugim (zgleda da windowsi queujajo click evente na gumb nekam in mu jih servirajo ko konca z loopom ...

zanimivo je pa da tudi ce dodam na zacetek funkcije button1_Click.... dodam: button1.Enabled = false;
in na konec: button1.Enabled = true;

je potem gumb sive barve... ampak klike pa se vedno lepo si zapomne kot da sploh nebi ibl disablean.... najbrz zato ker zadnja stvar preden pride ven iz svojega loopa se button samega sebe spet enablea in windowsi mu potem posljejo da se je zgodil click event na njega in ker je enablean v tistem trenutku ga pac sprocesira (in sam sebe spet takoj disablea)... rezultat je pac da veselo klikas po sivem gumbu


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Visual Basic

Oddelek: Programiranje
313192 (2218) cekr
»

Delphi - izdelava igre

Oddelek: Programiranje
81093 (866) Nextor
»

C# Pomoč

Oddelek: Programiranje
131310 (1135) jizzer
»

POMOČ: C# Spremenitev spremenljivke medtem ko teče ukaz while

Oddelek: Programiranje
91570 (1327) Ericssony
»

[VB.NET] Izpisovanje v TextBox in prekinitve

Oddelek: Programiranje
121180 (873) darkolord

Več podobnih tem