3

私は現在、一連のデリゲートを起動するためにイベントを使用しています。残りのデリゲートが別のデリゲート内から起動するのを防ぐことができる必要があります。

次のコードはシナリオを複製します...

//nonsense class
public class Foo {
    public string Bar { get; set; }
}

//nonsense event.
public event Action<Foo> SomeEvent;

void BindAndFire() {
    //wire it up.
    SomeEvent += (foo) => { 
        var a = DateTime.Now.Millisecond % 2;
        foo.Bar = (a == 0) ? "Hooray" : "Boo";
    };
    SomeEvent += (foo) => { 
        if(foo.Bar == "Boo") {
            SomeEvent.CANCEL_THE_REST(); //what do I do here?
        }
    };
    SomeEvent += (foo) => { 
        foo.Bar += ", you made it!";
    };

    //fire the event.
    SomeEvent(new Foo());
}

上記を考えると、私は何をする必要がありますか?アクションのリストなどに変更しても100%問題ありませんが、後続のイベントの実行を停止できるはずです。

注:示されているコードは、問題を複製するためのものであり、私のプログラム構造ではありません。実際のプログラムは着信ネットワークイベントを処理しており、それらで実行される任意のデリゲートのリストがあります...1つの問題についてそのすべてを投稿したくありませんでした。

...多分私はそれらを意図されていない方法で使用しようとしているだけです、私はそれで大丈夫です、私はただイベントについていくつかの新しいことを学ぶ必要があるだけだと思っていますC#。

お時間をいただきありがとうございます!

4

2 に答える 2

2

HandledEventArgsのようなものを使用する(または同様の概念を使用する)ことができます。これにより、イベントが処理されるときに、「handled」プロパティを設定し、他のデリゲートでこのプロパティを確認します。

他のすべての呼び出しを強制的にキャンセルできるかどうかわからないため、後で実行すると、デバッグが少し面倒になる可能性があります。

于 2012-06-25T00:49:47.163 に答える
1

私は自分の質問に答えたかもしれないと思います。

最終的には、デリゲートにブール値を返してもらい、イベントを実行するときに、実際にGetInvocationList()を使用してデリゲートを取得して呼び出し、戻り値を確認します...

新しいコードは次のようになります。

//nonsense class
public class Foo {
    public string Bar { get; set; }
}

//nonsense event.
public event Func<Foo, bool> SomeEvent;

void BindAndFire() {
    //wire it up.
    SomeEvent += (foo) => { 
        var a = DateTime.Now.Millisecond % 2;
        foo.Bar = (a == 0) ? "Hooray" : "Boo";
        return true;
    };
    SomeEvent += (foo) => { 
        return foo.Bar != "Boo";
    };
    SomeEvent += (foo) => { 
        foo.Bar += ", you made it!";
        return true;
    };

    //fire the event.
    var f = new Foo();
    foreach(var s in SomeEvent.GetInvocationList()) {
        if(!s.DynamicInvoke(f)) break;
    }
}

編集:私は自分の答えと上記のブルーベリーの組み合わせを使用することになりました。それは私が取り組んでいることに適していたからです。したがって、私の場合、イベント引数の1つにClose()メソッドがあり、開発者がデリゲート内で呼び出す可能性があります。そこで、GetInvocationList()をループしながらチェックして中断するプロパティを設定していました。

//nonsense class
public class Foo {
    public string Bar { get; set; }
    public bool IsClosed { get; private set; }
    public void Close() {
        IsClosed = true;
    }
}

//nonsense event.
public event Action<Foo> SomeEvent;

void BindAndFire() {
    //wire it up.
    SomeEvent += (foo) => { 
        var a = DateTime.Now.Millisecond % 2;
        foo.Bar = (a == 0) ? "Hooray" : "Boo";
    };
    SomeEvent += (foo) => { 
        if(foo.Bar != "Boo") {
           foo.Close();
        }
    };
    SomeEvent += (foo) => { 
        foo.Bar += ", you made it!";
    };

    //fire the event.
    var f = new Foo();
    foreach(var s in SomeEvent.GetInvocationList()) {
        s.DynamicInvoke(f);
        if(f.IsClosed) break;
    }
}
于 2012-06-25T00:46:07.320 に答える