3

いくつかのカスタムイベントを作成したいのですが、これは常にイベント登録の逆の順序で登録済みのイベントハンドラーを呼び出します。つまり、最後に登録されたイベントハンドラーが常に最初に呼び出されます。出来ますか?これらのイベントは、特定のエラー状態でBusiness Layerクラスによって発生し、登録されたイベントハンドラーがエラー状態を克服できる場合があります。

それが可能かどうか、それは純粋に技術的な問題ですか?イベントチェーンの呼び出し順序を上書きすることは可能ですか?言語(C#2.0、3.0、4.0の任意のバージョン)はこの機能をサポートしていますか?

編集:

可能性のある使用法は、可能な場合はエラー報告とエラー回復です。たとえば、FuncAがFuncCを呼び出すFuncBを呼び出します。FuncCでエラー状態が発生し、そのイベントが発生する場合があります。FuncAとFuncBは、エラー回復メカニズムを提供できる場合、イベントに登録しているはずです。Func Bはエラーを解決するためのコンテキストを持っている可能性が高いため、最新の登録済みハンドラーを呼び出し、イベント引数をチェックしてエラーが解決されたかどうかを確認します。はいの場合、他のイベントハンドラーも呼び出しません。いいえの場合、2番目に最近登録されたハンドラーを呼び出します。これは、呼び出し元の呼び出し元関数、つまりFuncAになります。

ほとんどの場合、コードは通常、FuncAがFuncBを呼び出す場合、FuncBがFuncAを呼び出さないように構造化されます。つまり、循環呼び出しは通常存在せず、イベントハンドラーの順序は関数呼び出しの順序と同じになります。したがって、FuncAがFuncCを呼び出すFuncBを呼び出し、Func Cが「エラーイベント」を発生させた場合、エラーを処理するのに最も適した候補は、Func Bのイベントハンドラーであり、次にFuncAのイベントハンドラーなどです。

これは、スタックトレースの巻き戻しのようなものであり、最新の呼び出し元関数にイベントを消費する機会を与えます。いいえ。呼び出し元の関数の数がそこにある可能性があります。

イベントがいずれかのハンドラーによって正常に消費された後、「エラーイベント」を発生させたFuncCが続行します。これを決定するためにイベント引数をチェックします。ハンドラーがイベントを消費していない場合、FuncCは例外をスローします。

4

1 に答える 1

4

はい、MulticastDelegate.GetInvocationList()メソッドを使用して、イベントの呼び出しリストを自分で繰り返すことができます。このような:

    public event EventHandler Custom;

    protected virtual void OnCustom(EventArgs e) {
        var handler = Custom;
        if (handler != null) {
            var subscribers = handler.GetInvocationList();
            for (int ix = subscribers.Length - 1; ix >= 0; --ix) {
                var sub = (EventHandler)subscribers[ix];
                sub(this, e);
            }
        }
    }

これは気の利いた解決策であることに注意してください。他のコードがイベントをサブスクライブする順序を制御することはできません。

于 2013-03-08T19:02:39.767 に答える