23

トラップが発生したときに、すべてのサブスクライバーにアラート メッセージを送信したいと考えています。

私が作成したコードは、デリゲート メソッドを使用して正常に動作しますmyDelegate del

私の質問は次のとおりです。

  1. EventHandlerデリゲートの代わりに使用する方が良いかどうか知りたいですか? 私の場合、デリゲートとの違いが何であるかわかりませんEventHandler

  2. notify(trapinfo t)、それがトラップ情報を取得するためにここで行ったことです。しかし、それは良い考えではないようです。デリゲート オブジェクトの受け渡しを紹介するオンライン チュートリアル レッスンを読みました。私の場合、それが適切かどうか疑問に思っていますか?そして、どうすればいいですか?助言がありますか?

どうもありがとう :)

私のコード:

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();
        }
    }

2013-08-12 更新

オブザーバー/オブザーバブルデザイン パターンはどうですか。私の場合は見栄えがします ( EventHandler)。

私の場合、マシンはトラップ メッセンジャーにサブスクライブします。(呼び出しリストにマシンを追加) トラップが発生したら、サブスクライブしているすべてのマシンにメッセージを送信します。(お電話HandleEventで対応いたします)

利点:

  • もう気にする必要はありませんGetInvocationList()。and を使用(+=)(-=)て、誰にトラップを送信するかを決定してください。

  • プログラムのロジックを理解しやすくなります。

いくつかの方法があることは知っていますが、その長所と短所を分析できればと思います。

そして、あなたのコメントや提案に感謝します, それは非常に役に立ちます!

Matthew Watson が提案したMSDN EventArgsの記事を読みました。

ここに私のイベントバージョンがあります:

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();
    }
}
4

2 に答える 2

8

あなたの例にはを使用する方がはるかに優れていeventます。

  • Aneventは Visual Studio フォームおよび WPF デザイナーによって理解されるため、IDE を使用してイベントをサブスクライブできます。

  • を発生させる場合、それらを反復処理するeventsために独自の処理を記述する必要はありません。foreach

  • eventsほとんどのプログラマーがこの機能へのアクセスを期待する方法です。

  • デリゲートを使用する場合、消費するコードは、防止したい方法 (呼び出しリストのリセットなど) でデリゲートをいじることができます。eventsそれが起こらないようにしてください。

2 番目の質問については、データを保持するためにevent派生クラスを作成し、EventArgsそれを発生させたときにそれをイベントに渡します。その後、消費者はそれにアクセスできます。

詳細については、http: //msdn.microsoft.com/en-us/library/system.eventargs.aspxを参照してください。

于 2013-08-11T09:11:20.227 に答える