Avatar billede wmann Nybegynder
28. juli 2008 - 10:26 Der er 6 kommentarer

Stoppe event

Jeg er i den stiuation at jeg "måske" skal lave et program der udfører yderligere validering på nogle data i et andet program..
Jeg har så fundet ud af når der postes (ligges data ind i db) foretages der først validering og jeg kan fange et BeforeValidate-event.
Skide godt, men men men problemet bliver så blot at min validering skal stoppe valideringen fra selve programmet hvis den ikke godkendes (udfra mine yderligere krav til validering).
Min tanke var i første omgang at fange dette event og udføre noget kode, MEN..! Jeg skal være sikker på jeg er den første der fanger det, plus bagefter HVIS valideringen (min med yderligere krav) ikke godkendes skal jeg aldrig frigive dette event til andre.
Vil det overhovedet kunne lade sig gøre for det jeg temmeligt skeptisk overfor.
Og events er vel heller ikke så simpelt opbygget så der er en der får eventet af gangen og arbejder udfra det og så frigiver det så andre kan arbejde på det bagefter?
Det er vel mere at man kan abonnere på dette events og så vil ALLE få dette event samtidigt og udføre kode udfra dette?
Avatar billede md_craig Nybegynder
29. juli 2008 - 13:58 #1
Som svar på de sidste linier, så er svaret ikke helt...
Objecter der abonnere på events, får besked efter tur.

eks:

    class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            EventRaiser raiser = new EventRaiser();

            new EventListener(raiser, 'A');
            new EventListener(raiser, 'B');
            new EventListener(raiser, 'C');
            new EventListener(raiser, 'D');
            new EventListener(raiser, 'E');

            raiser.RaiseEvents();
        }
    }

    public class EventRaiser
    {
        public event EventHandler<EventArgs> Bump;
        public void RaiseEvents()
        {
            if (Bump != null)
                Bump(this, EventArgs.Empty);
        }
    }

    public class EventListener
    {
        private char id;
        public EventListener(EventRaiser listee, char id)
        {
            this.id = id;
            listee.Bump += Bump;
        }

        void Bump(object sender, EventArgs e)
        {
            for (int i = 0; i < 100; i++)
            {
                Console.Write(id);
                Thread.Sleep(10);
            }
        }
    }

... Kan måske give et hint...

Men... Men dette er jo inde for en enkelt applikation, det jeg ikke helt kan lurer er om du mener andre apps der også har subscribet på et event nede fra en database, i såfald ja. så bliver de udført "samtidig".

Så skal dit program stoppe et andet program i en opperation hvis din validering fejler?...
Avatar billede wmann Nybegynder
29. juli 2008 - 14:12 #2
Hvis de kommer efter tur kan jeg så se rækkefølgen et sted?

For sagen er jeg skal udvikle en udvidelse til et program jeg ikke selv har udviklet..

Den skal gemme noget i en database og når dette sker skal den først validere data.. Den har derfor et beforePost-event, et Post-Event, et beforeValidate-Event og et BeforeValidate-event.
Dette gør selvfølgelig at når beforeValidate kaldes er det muligt for programmet at validere data og afbryde hvis valideringen ikke går godt. Den vil så kaste Validate-Eventet og så vil den fortsætte. Smart måde at kunne afgøre om du skal fortsætte eller ej.

Så vil jeg kunne sikre mig jeg (min extension/udvidelse) er den første der får dette event fra programmet og ikke programmet selv?
Da jeg skal lave yderligere validering og sikre mig BeforeValidate ikke sætter en validering igang hvis min egen validering ikke godkendes.
Avatar billede md_craig Nybegynder
29. juli 2008 - 14:59 #3
Ja i principet, jeg tror dog problemet for dig er at Eventet bliver raised fra kode du ikke har ejerskab over?... for kun inde fra klassen selv kan du tilgå disse ting. fx:

    public class EventRaiser
    {
        public event EventHandler<EventArgs> Bump;
        public void RaiseEvents()
        {
            if (Bump != null)
                Bump.Invoke(this, EventArgs.Empty);

            for (int i = 0; i < 10; i++)
            {
                Console.Write("0");
                Thread.Sleep(10);
            }
        }
        public void PrintInvokationList()
        {
          foreach (Delegate target in Bump.GetInvocationList())
          {
              Console.WriteLine(target.Method.Name);
          }
        }
        public bool IsFirstInLine(object target)
        {
            return Bump.GetInvocationList()[0].Target == target;
        }
    }

Rækkefølgen kommer af hvem der subscriber først.

Det der nok ville være mest hensigtsmessigt for dig ville være hvis du kunne få de andre til at subscribe dig istedet for det orginale event. Så kunne du gøre din validering, og så kun vidersende eventet efter om ting er OK eller ej.

Men uanset hvad, kræver det nok at du kan lave om i enten de eksisterende subscribers (Reroute hvad de lytter på), eller at du kan tilrette det de subscriber på... ellers er det nok en noget mere kompliceret affære, (hvis det overhovdet kan lade sig gøre.)
Avatar billede wmann Nybegynder
29. juli 2008 - 15:14 #4
Så kan jeg godt se det nok desværre er umuligt..
Jeg blir nødt til at lave en knap der laver min validering og hvis den går godt kaster jeg det event der aktiverer deres validering..
Du skal self. ha point som tak for hjælpen
Avatar billede md_craig Nybegynder
29. juli 2008 - 15:40 #5
Det er også en ganske udemærket løsning IMO... Hvis du er lidt heldig med interfaces osv kan følgende måske inspirerer lidt:

    class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            //Console.WriteLine("Process ID: " + Process.GetCurrentProcess().Id);
            //Console.WriteLine("AppDomain ID: " + AppDomain.CurrentDomain.Id);
            //Console.WriteLine();

            //Console.WriteLine(Dns.GetHostName());
            //IPAddress adr = Dns.GetHostAddresses(Dns.GetHostName())[0];
            //Console.WriteLine(string.Join(".", Array.ConvertAll<byte, string>(adr.GetAddressBytes(), delegate(byte b) { return b.ToString(); })));
         
            //string message = "";
            //while (message != "Exit")
            //{
            //    Console.WriteLine("Type a message do encrypt and decrypt: ");
            //    byte[] input = Encoding.ASCII.GetBytes(Console.ReadLine());

            //    MemoryStream incrypted = new MemoryStream();
            //    MemoryStream decrypted = new MemoryStream();

            //    CircEncryptionStream enc = new CircEncryptionStream(3, incrypted);
            //    CircDecryptionStream dec = new CircDecryptionStream(3, decrypted, enc.Permutation);

            //    foreach (byte data in input)
            //    {
            //        enc.Write(data);
            //    }
            //    byte[] encryptedBytes = incrypted.ToArray();
            //    Console.WriteLine("Encrypted message: " + Encoding.ASCII.GetString(encryptedBytes));
            //    Array.ForEach(encryptedBytes, delegate(byte data) { Console.Write(data+ " "); });
            //    Console.WriteLine();

            //    dec.Decrypt(incrypted);

            //    byte[] decryptedBytes = decrypted.ToArray();
            //    Console.WriteLine("Decrypted message: " + Encoding.ASCII.GetString(decryptedBytes));
            //    Array.ForEach(decryptedBytes, delegate(byte data) { Console.Write(data + " "); });
            //    Console.WriteLine();

            //    message = Encoding.Unicode.GetString(decryptedBytes);
            //}

            EventRaiser raiser = new EventRaiser();
            IRaiser newRaiser = new NewEventRaiser(raiser);

            EventListener a = new EventListener(newRaiser, 'A');
            EventListener b = new EventListener(newRaiser, 'B');
            EventListener c = new EventListener(newRaiser, 'C');
            EventListener d = new EventListener(newRaiser, 'D');
            EventListener e = new EventListener(newRaiser, 'E');

            raiser.RaiseEvents();
        }
    }

    public interface IRaiser
    {
        event EventHandler<EventArgs> Bump;
    }

    public class NewEventRaiser : IRaiser
    {
        public event EventHandler<EventArgs> Bump;
        public NewEventRaiser(EventRaiser adaptee)
        {
            adaptee.Bump += BumpExtention;
        }

        void BumpExtention(object sender, EventArgs e)
        {
            //Do some extra checks here

            if (Bump != null)
                Bump.Invoke(this, e);
        }
    }

    public class EventRaiser : IRaiser
    {
        public event EventHandler<EventArgs> Bump;
        public void RaiseEvents()
        {
            if (Bump != null)
                Bump.Invoke(this, EventArgs.Empty);
        }
    }

    public class EventListener
    {
        private char id;
        public EventListener(IRaiser listee, char id)
        {
            this.id = id;
            listee.Bump += Bump;
        }

        void Bump(object sender, EventArgs e)
        {
            for (int i = 0; i < 100; i++)
            {
                Console.Write(id);
                Thread.Sleep(10);
            }
        }
    }

Her har jeg egentlig lagt et lign. mellemlag ind, men fordi jeg har lavet et interface der definere "Bump" og mine subscribers reagere på det interface istedet, så er omskrivnignen relativ let...

Det er naturligvis lidt svært at se om det er noget du kan bruge som inspiration, men om ikke andet var det måske en overvejelse hvis der senere skal laves om på det samme igen.
Avatar billede md_craig Nybegynder
29. juli 2008 - 15:41 #6
og hold da op, der kom lige noget udkemmenteret test kode med... ikke sådan når man sider og afprøver ting sammmentidig med man svare på spørgsmål ^^
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester