C # delegate v. s. eventHandler

Chcę powiadomić wszystkich subskrybentów, gdy pojawi się pułapka.

Stworzony przeze mnie kod działa dobrze za pomocą metody delegata(myDelegate del).

Moje pytania są..
  1. Chcę wiedzieć, czy warto używać Eventhandler better off delegate? nie wiesz, czym dokładnie różni się delegat od Wydarzenia w moim przypadku?

  2. Powiadom(trapinfo t), to jest to, co zrobiłem tutaj, aby uzyskać informacje pułapki. Ale to nie jest dobry pomysł. Przeczytaj trochę online tutorial lekcja przedstawiająca delegatów zdających obiekt, czy jest to odpowiednie dla mojego przypadku? I jak mam to zrobić? Jakieś sugestie?

Wielkie dzięki:)

Mój kod:

public class trapinfo
    {
        public string info;
        public string ip;
        public string cause;
    }

    public class trap
    {
        public delegate void myDelegate(trapinfo t);
        public myDelegate del;

        trapinfo info = new trapinfo();

        public void run()
        {
            //While(true) 
            // If a trap occurred, notify the subscriber
            for (; ; )
            {
                Thread.Sleep(500);
                foreach (myDelegate d in del.GetInvocationList())
                {
                    info.cause = "Shut Down";
                    info.ip = "192.168.0.1";
                    info.info = "Test";
                    d.Invoke(info);
                }
            }
        }
    }
    public class machine
    {
        private int _occuredtime=0;

        public trapinfo info = new trapinfo();
        public void notify(trapinfo t)
        {
            ++_occuredtime;
            info.cause = t.cause;
            info.info = t.info;
            info.ip = t.ip;
            getInfo();
        }
        public void subscribe(trap t)
        {
            t.del += new trap.myDelegate(notify);
        }
        public void getInfo()
        {
            Console.WriteLine("<Alert>: cauese/{0}, info/ {1}, ip/{2}, time/{3}",
                info.cause, info.info, info.ip,_occuredtime);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            trap t = new trap();
            machine machineA = new machine();
            machineA.subscribe(t);
            t.run();
        }
    }

Aktualizacja 2013-08-12

Może obserwator / obserwowalny wzorzec projektowy, który wygląda świetnie w moim przypadku. (EventHandler) Super-prosty przykład C # observer/observable z delegatami

W moim przypadku maszyna jest posłańcem-pułapką. (Dodaj maszynę do listy zaproszeń) Gdy pojawi się pułapka, wyślij wiadomość do wszystkich maszyn, które są subskrybowane. (Call HandleEvent to handle it)

Korzyść:

  • Nie obchodzi mnie już GetInvocationList (), wystarczy użyć ( + = ) i ( - = ), aby zdecydować, do kogo wysyłana jest pułapka.

  • Łatwo zrozumieć logikę mojego programu.

Wiem, że można to zrobić na kilka sposobów, ale chciałbym przeanalizować jego zalety i wady. I dzięki za komentarze i sugestie, że byłoby bardzo pomocne!

Czytałem artykuł MSDN EventArgs, który sugeruje Matthew Watson system.eventargs

Oto moja wersja Wydarzenia:

public class TrapInfoEventArgs : EventArgs
{
    public int info { get; set; }
    public string  ip { get; set; }
    public string cause { get; set; }
}
public class trap
{
    public event EventHandler<TrapInfoEventArgs> TrapOccurred;

    protected virtual void OnTrapOccurred(TrapInfoEventArgs e)
    {
        EventHandler<TrapInfoEventArgs> handler = TrapOccurred;
        if (handler != null)
        {
            handler(this, e);
        }
    }


    public void run()
    {
        //While(true) 
        // If a trap occurred, notify the subscriber
        for (; ; )
        {
            Thread.Sleep(500);
            TrapInfoEventArgs args = new TrapInfoEventArgs();
            args.cause = "Shut Down";
            OnTrapOccurred(args);
        }
    }
}
public class machine
{
    public void c_TrapOccurred(object sender, TrapInfoEventArgs e)
    {
        Console.WriteLine("<Alert>: cauese/{0}, info/ {1}, ip/{2}, time/{3}",
            e.cause, e.info, e.ip, DateTime.Now.ToString());
    }
}
class Program
{
    static void Main(string[] args)
    {
        trap t = new trap();
        machine machineA = new machine();
        t.TrapOccurred += machineA.c_TrapOccurred; //notify machine A
        t.run();
    }
}
Author: Community, 2013-08-11

2 answers

Różnica między wydarzeniem a delegatem jest taka, że:

Deklaracja zdarzenia dodaje warstwę ochrony na instancji delegata. Ta ochrona uniemożliwia klientom delegata zresetowanie delegować i jego listę wywołań, a jedynie umożliwia dodawanie lub usuwanie cele z listy inwokacji

Zobacz Jakie są różnice między delegatami a wydarzeniami?

2) Jak widzę Twój Abonent nie powinien się swobodnie zmieniać.Jeden abonent można przypisać " = "to zamiast dodawania"+=".Spowoduje to przypisanie nowego delegata, dlatego poprzedni delegat z listą wywołań zostanie utracony, a poprzedni subskrybenci nie będą już wywoływani. Więc powinieneś użyć Event na pewno. albo możesz zmienić swój kod, aby delegat był prywatny i napisać dodatkowe funkcje do manipulowania nim .więc będzie to twoje własne zachowanie eventowe .

 //preventing direct assignment
 private myDelegate del ;

    public void AddCallback(myDelegate m){
        del += m;
    }

    public void RemoveCallback(myDelegate m){
        del -= m;
    }

    //or
    public static trap operator +(trap x,myDelegate m){
        x.AddCallback(m);
        return x;
    }
    public static trap operator -(trap x, myDelegate m)
    {
        x.RemoveCallback(m);
        return x;
    }

//usage  

//t.AddCallback(new trap.myDelegate(notify));
  t+=new trap.myDelegate(notify);
 17
Author: qwr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:09:54

O wiele lepiej jest użyć event jako przykładu.

  • An event jest rozumiany przez Visual Studio Form i projektantów WPF, więc możesz użyć IDE, aby subskrybować wydarzenia.

  • Podczas podnoszenia events, nie ma potrzeby, aby pisać własną obsługę foreach, aby iterację przez nie.

  • events to sposób, w jaki większość programistów oczekuje dostępu do tej funkcjonalności.

  • Jeśli używasz delegata, kod zużywający może bawić się z nim w sposób, któremu chcesz zapobiec (np. zresetować listę wywołań). Nie pozwól na to.

Jeśli chodzi o drugie pytanie: używając event tworzysz klasę pochodzącą z EventArgs, która przechowuje Dane i przekazuje je zdarzeniu, gdy je podnosisz. Konsument będzie wówczas miał do niego dostęp.

Zobacz tutaj po szczegóły: http://msdn.microsoft.com/en-us/library/system.eventargs.aspx

 8
Author: Matthew Watson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-11 09:11:20