2

任意の方法で相互に接続されたオブジェクトの大規模なネットワーク間で、電気やガスなどのリソースの分布をシミュレートする必要があるアプリケーションを作成しています。物理をシミュレートする必要はありません。オブジェクトがリソースを要求したときのリソースのユニットの流れだけです。

以下の図を検討してください。

ObjA <---> ObjB <---> PwrA <---> ObjF
            /\                                ObjG
   ObjE<---/  \---> PwrB

Pwrオブジェクトは、 Objオブジェクトから要求されたときにリソースの電気を提供できます。ここでシミュレートする必要があるのは、ObjA が 50 電力を必要とする場合、ObjA は接続先のピアすべてにメッセージを送信し、直接または間接的に接続されているピアからのみリソースを取得する必要があるということです。

ここでは遅延などをシミュレートしていないので、送信は即座に行われます。プログラミングの観点からは、これはすべてアプリケーション内で完全にローカルです (実際のネットワークなどはありません)。

ここでの私の課題は、モジュール化されたクリーンな方法でこれをプログラムしようとすることです。可能であれば、ローカルに接続されたノードの巨大なリストと、メッセージの処理方法に関する大きな ifelse ステートメントは避けたいと思います。

目標を達成すると同時に、何か新しいことを学びたいです。ここ数週間、記事や本、プログラミングの概念を読んできましたが、素晴らしい解決策になると思うのは C# Delegates です。

私はいくつかのプロトタイピングを行い、接続された他のオブジェクトがサブスクライブして処理する送信メッセージをリッスンできる MessageOut Delegate を使用してオブジェクトをセットアップすることができました。

これは非常にうまく機能しますが、コンセプトの経験が浅いため、次の欠点があります。

  • 接続されたオブジェクト間のメッセージ パッシングで循環参照を処理する方法がわかりません: 上の図で、ObjB が電気のメッセージをブロードキャストすると、ObjA、PwrA、PwrB、ObjE が通知され、すべてのプロセスが順番に処理されてから ObjB に通知されます。 . 次に通知します...など。ネットワークがこれを処理する方法は、デリゲートを受信したポートを除くすべてのポート (デリゲートをリッスンするオブジェクト) をブロードキャストすることです。これをデリゲートで実装するにはどうすればよいですか? フラットなブロードキャストは機能しません。
  • デリゲートの話を聞くと、一方通行のコミュニケーションが効果的に作成されます。双方向通信を実装するには、オブジェクトが相互に発信メッセージをリッスンする必要があります。しかし、上記の別の循環参照がない場合はどうなりますか?
4

4 に答える 4

1

イベントを操作している場合、すべてのイベント デリゲートに "sender" オブジェクトと "EventArgs" を含めることがベスト プラクティスであることに気付くでしょう。

私は一度そのようなことをしなければなりませんでした。そして、思いついた解決策は、「OriginalSender」を EventArgs 派生クラスに追加することでした。

受信したすべてのメッセージは、最初に if ステートメントに渡されます。

class MyEventListenerClass
{
     .....
    private void EventHandlerMethod(object sender, MyEventArgs E)
    {
        if (E.OriginalSender != this)
        { 
            do what is needed
        }
        else
        {
            got this message from myself in a circular way....discard it
        }
    }
     ......
}


class MyEventArgs : EventArgs
{
    public object OriginalSender {get; private set;}
    public MyEventArgs(object OrigSender) : base ()
    {
        OriginalSender = OrigSender;
    }
}

しかし、それですべてが解決するわけではありません。私の場合、元の送信者を含まないループはありませんでした。メッセージがそのようにループに陥ると、それは無限になります。したがって、送信者のリストで解決できる可能性がありif (E.SenderList.Contains(this)) {...}ます。したがって、メッセージを受信するたびに、受信者はリストに自分自身が含まれているかどうかを確認します。そうでない場合は、送信者リストに自分自身を追加してメッセージを送信します。

于 2013-04-03T12:43:21.793 に答える