最近、C#のイベントハンドラを使って実装しているのですが、内部的にどのように処理されてるかがイメージできません。
例えば、C#で下記のようにTimerクラスのインスタンスにfunc関数をイベントハンドラとして登録しているのですが、内部的にはこのfunc関数の実行トリガーは、ポーリングで実現しているのでしょうか、それともobserverパターンで実現しているのでしょうか。
DispatcherTimer timer= new DispatcherTimer(); timer.Tick += func();
また、この他にも内部処理が知りたい場合、有用なサイトや本等、ご存知の方いらっしゃいましたらご教授いただけたら幸いです。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
発砲している場所は
.NET Core wpf/DispatcherTimer.cs at master · dotnet/wpf
.NET Framework DispatcherTimer.cs
ですね。
追っていくとWin32
のSetTimer
になっているようですが、この先はわかりません^^;
投稿2020/05/13 11:03
編集2024/08/31 18:06総合スコア9884
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
昔の Microsoft のチュートリアルで自分的に参考になった記事のコードが残っていたのでご参考に貼っておきます。サイトはすでにリンク切れで読めません。
// イベントとは、オブジェクトでクライアントに有益な事象が発生したときに、クラスからクライ // アントへ通知する方法のこと。 // // イベント使用の典型的な例は Windows フォームのコントロール。通常、インターフェイスのコ // ントロールを表すクラスには、ユーザーがコントロールに対して何らかの操作 (ボタンのクリッ // クなど) を行ったときに通知されるイベントが設定されている。 // // イベントの宣言には、デリゲートを使用する。イベントが発生すると、クライアントによって // フックされたデリゲートが呼び出される。 // 2015/2/7 以下のページを見つけたのでメモしておく: // 方法 : .NET Framework ガイドラインに準拠したイベントを発行する (C# プログラミング ガイド) // https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/events/how-to-publish-events-that-conform-to-net-framework-guidelines // 方法 : 派生クラスから基本クラス イベントを発生させる (C# プログラミング ガイド) // https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/events/how-to-raise-base-class-events-in-derived-classes using System; using System.Collections; namespace MyEventTest { // 宣言されていない場合は、最初にイベントのデリゲート型を宣言する必要がある。sender // はイベントが発生したオブジェクトへの参照。e はイベントデータが格納されているオブ // ジェクトへの参照。 // ライブラリの EventHandler を使う場合は、宣言済みらしく、この宣言は不用。 // 引数はライブラリの EventHandler と合わせているが、このサンプルでは使っていないの // で、ChangeEventHandler(引数なし) として書き直しても同じ結果になる。 public delegate void ChangedEventHandler(object sender, EventArgs e); public class ListWithChangedEvent : ArrayList { // イベントの宣言 // event キーワードに注意。 // クラスの外からはフィールドのように見える。ただし、アクセスには制限があり、実行で // きるのは、以下の処理だけ。 // ・新しいデリゲートの結合 // ・(結合されている場合は)デリゲートの削除 // これらの処理には、+= および -= 演算子を使用する。下記の EventListener クラス参照 public event ChangedEventHandler Changed; // イベントの起動 // デリゲートをイベントにフックしているクライアントがない場合、フィールドは null に // なる。それ以外の場合は、イベント起動時に呼び出すデリゲートへの参照となる。このた // め、一般にイベントが起動される場合はまずこのフィールドが null かどうかを調べ、そ // の後イベントを呼び出す。 // イベントは、イベントを宣言したクラスの中からしか起動できない。イベントを起動する // protected メソッドを作成しておき、このメソッドを呼び出すことによって、派生クラスが // イベントを起動できる。さらに柔軟性を持たせるために、起動メソッドを virtual とし // て宣言することも多くある。これにより、派生クラスは、そのメソッドをオーバーライド // できる。 protected virtual void OnChanged(EventArgs e) { if (Changed != null) Changed(this, e); } // リストへの追加、リストのクリア、リストの要素への代入の際にイベントを起動(具体的 // には EventListener が Changed に結合したメソッド ListChanged を呼ぶ)。 public override int Add(object value) { int i = base.Add(value); OnChanged(EventArgs.Empty); // Empty の他に何がある??←無い。下記の説明を参照 return i; } // <ヘルプの EventArgs クラスの説明> // このクラスにはイベント データは格納されません。このクラスは、イベントの発生時にス // テータス情報をイベントハンドラに渡さないイベントによって使用されます。イベントハン // ドラがステータス情報を必要とする場合、アプリケーションは、そのデータを保持するため // に、このクラスからクラスを派生させる必要があります。 public override void Clear() { base.Clear(); OnChanged(EventArgs.Empty); } public override object this[int index] { set { base[index] = value; OnChanged(EventArgs.Empty); } } } } namespace TestEvents { using MyEventTest; class EventListener { private ListWithChangedEvent List; // イベントのフック // イベントの呼び出しの受け取りを開始するには、クライアントコードはまず、イベント // から呼び出されるメソッドを参照するイベント型のデリゲート(以下のコードで言うと、 // new ChangedEventHandler(ListChanged) )を作成する。 // 次に、+= を使用して、イベントに接続される他のデリゲートに、このデリゲートを結 // 合する。 public EventListener(ListWithChangedEvent list) { List = list; List.Changed += new ChangedEventHandler(ListChanged); } // イベントから呼び出されるメソッド。 private void ListChanged(object sender, EventArgs e) { Console.WriteLine("This is called when the event fires."); } // クライアントコードは、-= 演算子を使用してイベントからデリゲートを削除できる。 public void Detach() { List.Changed -= new ChangedEventHandler(ListChanged); List = null; } } // サンプルプログラムにもう一人 Listener を追加 class AnotherEventListener { private ListWithChangedEvent List; public AnotherEventListener(ListWithChangedEvent list) { List = list; List.Changed += new ChangedEventHandler(ListChanged); } private void ListChanged(object sender, EventArgs e) { Console.WriteLine("追加したもう一人の Listener に通知"); } public void Detach() { List.Changed -= new ChangedEventHandler(ListChanged); List = null; } } class Test { public static void Main() { ListWithChangedEvent list = new ListWithChangedEvent(); EventListener listener = new EventListener(list); AnotherEventListener anotherListener = new AnotherEventListener(list); list.Add("item 1"); list.Clear(); listener.Detach(); // += した順に関係なく、不要となったデリゲートを -= で削除できる list.Add("item 2"); list.Clear(); anotherListener.Detach(); } } } // C# 言語では任意のデリゲート型のイベントを使用できるが、.NET Framework ではイベントに使用で // きるデリゲート型に厳密なガイドラインがある。適正なデリゲート型の EventHandler が .NET // Framework によって既に定義されている。上記のサンプルで、イベントのデリゲート型を宣言を削除 // し、ChangedEventHandler を EventHandler と書き直せばよい。
参考になれば幸いです。
投稿2020/05/13 09:51
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
投稿2020/05/13 07:51
総合スコア8947
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/05/14 11:09
2020/05/14 11:46
2020/05/14 11:50
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。