1

私はまだこのようなことの初心者であり、イベントとそれらを適切に使用する方法をよりよく理解しようとしています.

一連のオブジェクトを格納するコンテナーを持つマネージャー クラスがあります。各オブジェクトにはイベントがあります (基本的に、そのオブジェクトが行うことを実行したことを示します)。マネージャー クラスがイベントをサブスクライブし、イベントが発生したときにコンテナーからオブジェクトを削除したいと考えています。

オブジェクトのイベントに登録すると、そのオブジェクトのすべてのインスタンスに登録されますか、それともインスタンス固有ですか?

だからここに私が見ているもののようなものがあります:

 class MyManager
{
    private ConcurrentDictionary<string, MyObject> m_myObjectCollection;

    public MyManager()
    {
        m_myObjectCollection = new ConcurrentDictionary<string, MyObject>();


    }


    private void RemoveObject(MyObject myObject)
    {
        //remove object from collection
    }
}


class MyObject
{      

    public delegate void MyObjectFinished_EventHandler(object source, EventArgs e);

    public event MyObjectFinished_EventHandler OnFinished;

    public MyObject()
    {

        this.OnFinished += new MyObjectFinished_EventHandler(MyObject_OnFinished);

    }

    private void MyObject_OnFinished(object source, EventArgs e)
    {
        //do some clean up stuff
    }

    private void DoStuff()
    {
        //do stuff until finished
        OnFinished(this, new EventArgs());
    }

マネージャー クラスで MyObject のインスタンスを作成し、そのオブジェクトのイベントに登録するだけで十分ですか? それは私には正しくないようです。私の本能は、そのオブジェクト タイプのすべてのインスタンスではなく、その 1 つのオブジェクトのイベントにのみ登録されると言っています。

それとも、コレクションに追加するときに各 MyObject に登録し、削除したら登録を解除する必要がありますか?

または、これを完全に処理するより良い方法はありますか?

4

2 に答える 2

0

オブジェクトのイベントに登録すると、そのオブジェクトのすべてのインスタンスに登録されますか、それともインスタンス固有ですか?

はい、あなたの場合、コンストラクター内のすべてのオブジェクトインスタンスにイベントを配線しています.so、イベントはすべてのインスタンスで利用できます。

オブジェクトのすべてのインスタンスに対して、新しい Event/Delegate オブジェクトが作成されます。

それとも、コレクションに追加するときに各 MyObject に登録し、削除したら登録を解除する必要がありますか?

新しく作成されたオブジェクト インスタンスにイベントを接続することで、既にこれを行っています。各オブジェクトからイベントを手動で削除する方法を用意するか、ガベージ コレクターに任せてジョブを実行することもできます。イベント オブジェクトは、それを使用するオブジェクトがメモリ上にあるか、ガベージ コレクトされていない限り存続します。 .

于 2013-05-07T03:07:20.190 に答える
0

MyManager で作成する MyObject のインスタンスごとに MyObjectFinished_EventHandler を処理する関数を登録する必要があります。

private void CreateObjects()
{
    for (int i = 0; i < 100; i++)
    {
        MyObject o = new MyObject();
        o.OnFinished += OnMyObjectFinished;
        m_myObjectCollection.TryAdd(i.ToString(), o);
    }
}

ハンドラーは次のようになります。

private void OnMyObjectFinished(object source, EventArgs e)
{
    MyObject o = (MyObject)source;
    RemoveObject(o);
}

ご覧のとおり、ソースを MyObject 参照にキャストし、それを使用して必要な処理を行います。

編集: もう 1 つ明確にしたかったのは、OnFinished イベントをサブスクライブして MyObject クラスのクリーンアップ関数を呼び出しているということです。それは機能しますが、より簡単なのは DoStuff() でクリーンアップ関数を直接呼び出すことです。

public delegate void MyObjectFinished_EventHandler(object source, EventArgs e);

    public event MyObjectFinished_EventHandler OnFinished;

    public MyObject()
    {
    }

    private void Finished()
    {
        //do some clean up stuff
    }

    public void DoStuff()
    {
        //do stuff until finished
        Finished();
        OnFinished(this, new EventArgs());
    }

イベントは通常、何かが起こったことを他の人 (別のオブジェクト) に通知するために使用されます。

于 2013-05-07T03:01:27.900 に答える