私はこれがここでこの質問のわずかに複製であることを知っています:イベントのブロックと待機
しかし、私はEventWaiterを作成している途中で、問題が発生しました。これが私が取り組んできたものの(主に)簡略化されたバージョンです:
public class EventWaiter
{
private AutoResetEvent _autoResetEvent = new AutoResetEvent(false);
private EventInfo _event = null;
private object _eventContainer = null;
public EventWaiter(object eventContainer, string eventName)
{
_eventContainer = eventContainer;
_event = eventContainer.GetType().GetEvent(eventName);
}
public void WaitForEvent()
{
MethodInfo method = this.GetType().GetMethod("DynamicCaller");
Delegate handler = Delegate.CreateDelegate(this._event.EventHandlerType, this, method);
_event.AddEventHandler(_eventContainer, handler);
_autoResetEvent.WaitOne();
_event.RemoveEventHandler(_eventContainer, _handler);
}
public void DynamicCaller(/* insert magic here */)
{
_autoResetEvent.Set();
}
}
使用法は単純に次のようになります。
EventWaiter ew = new EventWaiter(someClass, "someEvent");
ew.WaitForEvent();
基本的に何が起こっているのかというと、DynamicCaller
このイベントのハンドラーとしてvoidを登録することです。問題は、イベントの署名が異なることです。使用するデリゲートに関係なく、イベントを処理できるようにしたいのです。
this._event.EventHandlerTypeを使用してデリゲートのタイプを取得できますが、デリゲートが何であっても、完全に再利用可能なクラスを作成するためにどのように使用できますか?DynamicCallerパラメーターがイベントデリゲートパラメーターと完全に同じでない場合、例外が発生します。
ちなみに、私はフレームワークのコードをたくさん調べました。その一部にアクセスできれば、これは簡単だと思います。私が必要とするクラスの多くがすべてフレームワークの内部にあるのは残念です。