非同期コールバックのマルチスレッド環境でイベント ハンドラーを適切に追加/削除する方法について質問があります。
アンマネージ コードからコールバックをディスパッチする ProxyDLL から非同期コールバックを受け取る MyCore クラスがあります。イベントをサブスクライブするフォーム(マネージド)があります。
イベントへのアタッチ/デタッチへの正しいアプローチは何でしょうか。MulticastDelegate に _invocationcount があることに気付きました。それは何をしますか?コールバックが完了するまでコールバック呼び出しが処理中の場合、イベントの内部ロジックはイベントからのデタッチをブロックしますか? その puprose に _invocationcount は存在しますか? イベントからのデタッチは (一般的に) トレッドセーフですか?
class Form1
{
EventHandler m_OnResponse;
Int32 m_SomeValue;
Form1()
{
m_OnResponse = new EventHandler(OnResponseImpl);
m_MyCore.SetCallBackOnLogOn(m_OnResponse);
}
~Form1()
{
m_MyCore.ReleaseCallBackOnLogOn(m_OnResponse);
}
private OnResponseImpl(object sender, EventArgs e)
{
Thread.Sleep(60*1000);
m_SomeValue = 1; // <<-- How to/Who guarantees that Form1 obj is still
// alive. May be callback was invoked earlier and
// we just slept too long
if (!this.IsDisposed)
{
invokeOnFormThread(DoOnResponseImpl, sender, e);
}
}
}
class MyCore
{
private event EventHandler OnLogOn;
public void SetCallBackOnLogOn(EventHandler fn)
{
// lock (OnLogOn)
{
OnLogOn += fn;
}
}
ReleaseCallBackOnLogOn(EventHandler fn)
{
// lock (OnLogOn)
{
OnLogOn -= fn;
}
}
public void DoDispatchOnLogOn()
{
// lock (OnLogOn)
{
if (OnLogOn != null)
{
OnLogOn(this, null);
}
}
}
}