Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Problem sa event handlerom

[es] :: .NET :: .NET Desktop razvoj :: Problem sa event handlerom

[ Pregleda: 1422 | Odgovora: 7 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

wex-alpha
Sarajevo

Član broj: 7580
Poruke: 845
109.175.81.*



+13 Profil

icon Problem sa event handlerom28.03.2011. u 09:35 - pre 158 meseci
Pozdrav,


Imam problem gdje mi se event handler ne poziva tada kada meni treba.

Program salje komande u uredjaj. Nakon svake komande sljedi odgovori. Taj odgovor moze biti razlicit i na osnovu tog odgovora moram tako i reagovati (greska? nema struje? blokirao uredja? itd..).

Imam sljedecu strukturu:

Handleri:
Code (csharp):


 fCom.OnIncomingData += new fCommunication.fCommunicationReceiveHandler(fCom_OnIncomingData);
                        fCom.OnTimeOut += new fCommunication.fCommunicationTimeOutHandler(fCom_OnTimeOut);
                        fCom.OnCRCError += new fCommunication.fCommunicationCRCErrorHandler(fCom_OnCRCError);



 

Kao i odgovarajuce metode (navodim samo jednu metodu radi prostora):

Code (csharp):

void fCom_OnIncomingData(object sender, fCommunicationEventArgs e)
        {
             
            if (checkBox_Batch.Checked == false)
            {
                this.textBox_receive.Text = fCom.CommunicationTools.ByteArrayToHexString(e.ReceiveMessageByte); //using the helper class for converting the incoming data to hex string
            }
            else
            {
                string line = "Receive: " + fCom.CommunicationTools.ByteArrayToHexString(e.ReceiveMessageByte) + "\n";
                this.richTextBox_Log.AppendText(line);
                incomingData.dataString = e.ReceiveMessageString;
                incomingData.dataByte = e.ReceiveMessageByte;
            }
        }

 



I na kraju while koji ceka odgovor.

Code (csharp):


incomingData.dataString = string.Empty; //isprazni podatke tako da novi stignu
...
while (incomingData.dataString == string.Empty)  //sve dok nema odgovora cekaj dok ne dodje
                    {

// ovo se vrti sve dok ne stigne odgovor iz uredjaja
Thread.Sleep(10);  //Pricekaj malo dok ne stigne odgovor
}
// dalje sljedi if-else struktura
 


Ovo savrseno radi, kada je standalone, hocu reci kada je u malom programu koji to testira. Problem nastaje kada ovo implementiram u vec gotovu aplikaciju. Onaj event handler koji puni string, se nikada ne zove i shodno tome while se zauvijek vrti u petlji.
Da mijenjam aplikaciju nije opcija, jer je vec ogromna.

Nasao sam dirty fix, koji rijesava problem sa event handlerom i nejgovim pozivom, ali onda kopletan sistem je sporiji za cirka 50%. Zato sto se sve uspori zbog pozivanja messagebox-a.

Ako recimo u while stavim ovo (oboje radi):

MessageBoxEx.Show("JAVI SE", 0) ili MessageBox.Show("JAVI SE")

dakle:

while (incomingData.dataString == string.Empty) //sve dok nema odgovora cekaj dok ne dodje
{

// ovo se vrti sve dok ne stigne odgovor iz uredjaja

MessageBoxEx.Show("JAVI SE", 0); //Obican message box, koji se automatski gasi. INT odredjue vrijeme gasenja u ms.

Thread.Sleep(10); //Pricekaj malo dok ne stigne odgovor
[/code]

Onda se event handler aktivira i obavi svoj posao. Zbog nekog razloga, jednom kada udje u while loop nikada ne izlazi iz njega, sve dok ne napravim "break" sa messagebox trikom.

Kako mogu eksplicitno da zovnem handler u ovom mom slucaju?
 
Odgovor na temu

Shadowed
Vojvodina

Član broj: 649
Poruke: 12846



+4783 Profil

icon Re: Problem sa event handlerom28.03.2011. u 10:02 - pre 158 meseci
Handler mozes pozvati jednostavno kao i bilo koju drugu funkciju (sto on i jeste). Medjutim, sto bi ga zvao? Ne vredi tebi da ga pozivas ako treba da ga pozove fCom koji ce mu dati podatke. Ti nemas koje podatke da mu das.
Inace, zasto uopste koristis taj while? Ako vec trebas uraditi nesto kada podaci stignu, smesti taj kod tamo gde je i logicno - u handler koji se poziva kada podaci stignu.
 
Odgovor na temu

wex-alpha
Sarajevo

Član broj: 7580
Poruke: 845
109.175.81.*



+13 Profil

icon Re: Problem sa event handlerom28.03.2011. u 10:12 - pre 158 meseci
Pa mislio sam da ga pozovem, bez da mu bilo sta prosljedim... samo da ga pokrenem.
 
Odgovor na temu

vujkev
Beograd

Član broj: 8072
Poruke: 1347
212.200.241.*



+104 Profil

icon Re: Problem sa event handlerom28.03.2011. u 10:58 - pre 158 meseci
Mislim da je Shadowed hteo da kaže šta će ti While petlja, ako već imaš OnIncomingData event. Stavi ceo kod koji zavisi od primljenih podataka u fCom_OnIncomingData proceduru koja i prima podatke.
Naučio sam...
Da je važnije biti ljubazan nego biti u pravu
 
Odgovor na temu

wex-alpha
Sarajevo

Član broj: 7580
Poruke: 845
109.175.73.*



+13 Profil

icon Re: Problem sa event handlerom28.03.2011. u 11:18 - pre 158 meseci
Stvar je u tome da ja nemam stalnu potrebu komunikacije sa uredjajem.

Kada se desi potreba, saljem niz komandi koje uredjaj treba da odradi:

Program stalno skenira okolinu (nekoliko ulaznih fajlova), i kada nadje komande u nekome tek onda zove metodu ZoviUredjaj()


Code (csharp):

 public void ZoviUredjaj()
{
 while (!this.batchAbbort && !abb) //checking the routine for break
            {
                for (int i = 0; i < papirproblem.kolekcija.Count(); i++) //koliko ima linija u kolekciji?
                {
                     
                    if (abb)
                        break;
                 
                     incomingData.dataString = string.Empty; //obrisi prethodne podatke koji su dobijeni iz uredjaja
                 

                    if (qCom != null)  //da li ima konekcije???
                    {
                        try
                        {
                            qCom.SendCommand((string)papirproblem.kolekcija[i]); //posalji komandu na spojeni uredjaj

                            reprint.pisiNaDiskBrojADA(i); // pisi na diski liniju po liniju
                            cuvampodatke.aktivacija = true;
                           
                           
                        }
                        catch (Exception ee)
                        {
                            MessageBox.Show("Aplikacija je izgubila vezu sa uredjajem"); //ako ne postoji veza
                            Process.GetCurrentProcess().Kill();  // ugasi program
                        }
                    }
                     
                    while (incomingData.dataString == string.Empty)  //pogledaj da li ima odgovora nakon zadnje komande
                    {
                         
                        MessageBoxEx.Show("Javi se", 0);//OVO JE TRIK KOJI OMOGUCAVA JAVLJANJE EVENTA
                     

                         
                       
                        Thread.Sleep(100);  //sacekaj malo dok se javi uredjaj
                     
                        if (this.batchAbbort) //korisnik prekinuo... ne koristi se
                        {
                         
                            abb = true;
                            break;
                           
                        }

                        if (this.batchTimeOut)  //uredjaj se nije javio na vrijeme
                        {
                            abb = true;
                             
                            //Process.GetCurrentProcess().Kill(); //zavisno od buduce potrebe i dizajna
                            break;
                           
                        }
 


kako ovo sve strpati u event handler??? Ili napraviti nesto slicno?

Nista mi ne pada na pamet :(
 
Odgovor na temu

Shadowed
Vojvodina

Član broj: 649
Poruke: 12846



+4783 Profil

icon Re: Problem sa event handlerom28.03.2011. u 12:28 - pre 158 meseci
Citat:
wex-alpha: Stvar je u tome da ja nemam stalnu potrebu komunikacije sa uredjajem.

Upravo. A sa ovim while vrtis sve vreme iako nemas potrebu da komuniciras sa uredjajem.

Imas:

[code=csharp]
while (incomingData.dataString == string.Empty) //sve dok nema odgovora cekaj dok ne dodje
{

// ovo se vrti sve dok ne stigne odgovor iz uredjaja
Thread.Sleep(10); //Pricekaj malo dok ne stigne odgovor
}
// dalje sljedi if-else struktura
[/code]

Dakle, taj // dalje sljedi if-else struktura stavi u event handler jer on, koliko sam shvatio i treba da se izvrsi kada podaci stignu tj. kada se okine event.
 
Odgovor na temu

Boris B.
Ljubljana

Član broj: 213615
Poruke: 286
*.zaslon-telecom.si.



+14 Profil

icon Re: Problem sa event handlerom29.03.2011. u 09:48 - pre 158 meseci
Šta ti je taj incomingData? Ko to puni, gde i kada?

Ovde ti možda JIT kompajler optimizuje petlju, jer vidi da se incomingData.dataString ne menja u okviru petlje koja proverava da li je dataString prazan, pa ga ni ne proverava, tek kad dodaš msgBox.Show pauzu (što izazove SendMessage i jump izvan loopa) ti ga nateraš da ipak reevaluira.

Probaj da napraviš odvojen thread zapakovan u klasu koji će biti zadužen za komunikaciju sa uređajem. Da bi sačuvao redosled operacija i evenata trebalo bi da imaš FIFO listu komandi. Cela stvar bi izgledala nekako ovako:

Code (csharp):

public class DeviceManager
{
    private List<Action> _commandQueue = new List<Action>();

    //Public contract - javni metodi koje pozivaju drugi threadovi, samo se dodaje nova komanda u listu
    public void Command1(int param1, string param2) { _commandQueue.Add(new Action( () => HandleCommand1(param1, param2) ); }
    public void Command2(string param1, float param2) { _commandQueue.Add(new Action( () => HandleCommand2(param1, param2) ); }
    ...

    //Public events - eventi na koje se pretplacuju ostale klase
    public event EventHandler Command1Completed;
    public event EventHandler Command2Completed;
    ...

    //Private contract - komande koje se uvek izvrsava u threadu managera
    private void HandleCommand1(int param1, string param2)
    {
        Device.DoSometing(...)
        WaitForResponse(...)
        if (Command1Completed != null) Command1Completed(this, ...);
    }

    private void HandleCommand2(string param1, float param2);
    {
        Device.DoSometing(...)
        WaitForResponse(...)
        if (Command2Completed != null) Command2Completed(this, ...);
    }
    ...
   
    // Msg loop managera
    private void Execute()
    {
        while(!Terminated)
        {
            var lst = _commandQueue.ToList();   //Iskopiras komande u internu listu
            _commandQueue.Clear();   // i onda ocistis komande
            foreach(var action in lst)   // zatim okidas komande jednu po jednu
                action();
         }
    }
}
 


Naravno sve operacije sa _commandQueue moras da opkoliš sa lock(), moraš da implementiraš kreiranje, startovanje i (pravilno) zaustavljanje threada, ali bitan je princip. Po mom iskustvu ovo je jedini siguran način da komuniciraš sa spoljnim uređajem, lako se održava, nadgrađuje i debaguje. Ovo je nekada bilo daleko teže napraviti zbog pakovanja komandi i parametara da mogu da stanu u neku listu, ali sa automatskim closure-ima u C# (action) sad je boza.
if it walks like a duck and quacks like a duck, it could be a dragon doing a duck
impersonation.
 
Odgovor na temu

wex-alpha
Sarajevo

Član broj: 7580
Poruke: 845
77.78.239.*



+13 Profil

icon Re: Problem sa event handlerom03.04.2011. u 13:25 - pre 158 meseci
rijseio sam problem tako sto sam program razbio na dva dijela. Jedan radi samo evaulaviju i kontaktira drugi.

Hvala svima na savjetima :)
 
Odgovor na temu

[es] :: .NET :: .NET Desktop razvoj :: Problem sa event handlerom

[ Pregleda: 1422 | Odgovora: 7 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.