質問者
登録したイベントハンドラが処理される順番

質問
-
次の様に、イベントハンドラを登録した場合、
button.Click += new EventHandler(button_Click1);
button.Click += new EventHandler(button_Click2);button_Click1、button_Click2 の順にハンドラは処理(コール)されるものなのでしょうか。
テストしてみてた結果では「+=」で登録した順にコールされているたいなのですが、
仕様的にも「登録した順にコールされる」となっているのでしょうか?
もし、「登録した順にコールされる」のであれば、この登録された順番を変えたり、
既に登録されているイベントハンドラに、INSERT的な感じで、ハンドラの登録を
割り込ませたりって可能なのでしょうか?
button.Click += new EventHandler(button_Click1);
button.Click += new EventHandler(button_Click2);
// ここで何とか処理して、button_Click0 のハンドラを button_Click1 の前に割り込ましたいこの結果、buttonクリックで、 button_Click0、button_Click1、button_Click2 の順に
ハンドラがコールされる様にさせるのが理想なのですが。
こんな事って可能でしょうか?
皆様、ご教授願えますでしょうか。
宜しくお願い致します。
すべての返信
-
http://www.microsoft.com/japan/msdn/community/gdn/ShowPost-38995.htmこのあたりが参考になりますか?・汎用的には無理・対象を特定する場合、十分な権限があれば可能といったところです。
-
囚人さん、K.Takaokaさん、回答ありがとうございます。
>http://www.microsoft.com/japan/msdn/community/gdn/ShowPost-38995.htm
紹介して頂いたページでは、「イベントハンドラは登録した順に実行される」と解釈できる
のですが。私の解釈(読解)の仕方が間違っているのでしょうか?
>・汎用的には無理「汎用」とは「全ての言語で」という事でしょうか?>・対象を特定する場合、十分な権限があれば可能「対象」とは言語を指すのでしょうか?「権限」って何の権限? -
「マルチキャストデリゲートは呼び出し順が保証されているだろう」という話です。イベントはまた違います。
イベントはクラスが独自に実装できます。そして外部からは、イベントをどう実装しているのかを意識できません(してはいけません)。
以下は、イベントハンドラを登録した順とは逆に実行される例です。
Code Snippetusing System;
public delegate void StackEventHandler(object sender, EventArgs e);
class Hoge
{
System.Collections.Stack _stackEvent = new System.Collections.Stack();public event StackEventHandler StackEvent
{
add
{
_stackEvent.Push(value);
}
remove
{
// 削除は不可!
}
}public void Run()
{
while(_stackEvent.Count != 0)
{
StackEventHandler h = (StackEventHandler)_stackEvent.Pop();
h(this, EventArgs.Empty);
}
}
}class Class1
{
static void Main(string[] args)
{
Hoge h = new Hoge();
h.StackEvent += new StackEventHandler(h_StackEvent1);
h.StackEvent += new StackEventHandler(h_StackEvent2);
h.Run();
}private static void h_StackEvent1(object sender, EventArgs e)
{
Console.WriteLine("No 1");
}private static void h_StackEvent2(object sender, EventArgs e)
{
Console.WriteLine("No 2");
}
} -
ぶるーの さんからの引用 私の解釈(読解)の仕方が間違っているのでしょうか?
この点に関してはすでに他の方がかかれている通りで、解釈が微妙に間違っています。ぶるーの さんからの引用 >・汎用的には無理「汎用」とは「全ての言語で」という事でしょうか?.NET では、プログラム言語に依存して技術的な問題が発生することは非常に稀です。次の、>・対象を特定する場合、十分な権限があれば可能という内容とあわせて「対象を特定しない」という意味です。対象というのは、話題にあがっている「特定のイベントに、最初に実行したいイベントハンドラを挿入する」という行為に対する返答ですので、対象を特定するというのは、「System.Windows.Forms.Button の Click イベント」などというイベントの限定をさしています。それに対して「汎用的には不可能」というのは、「すべてのコントロールの」とか「XXX クラスのすべてのイベント」などという汎用化が可能な実装は非常に困難であるか不可能である、ということです。前述の URL のほうを見てもらえばわかるかもしれませんが、このような対象の特定を行う場合には、その実装にたいする理解や試行錯誤が多少あれば、どのような手段を用いてイベントハンドラが管理されているかを特定することが可能です。あとは、リフレクション等を利用することでそのイベントハンドラの管理部分を変更してやることで、イベントから呼び出されるイベントハンドラの順序を操作することが可能になるものは多くあります。一般的なコントロール類の実装では、イベントハンドラの管理部分は private などのアクセス制御を設定されており、外部から修正がきかないようになっていますので、それを無理やり変更するためには、ある程度の実行権限が必要です。(どのような操作にどのような権限が必要であるかは、MSDN などのドキュメントに記載されているはずです)