비동기식 콜백을위한 다중 스레드 환경에서 이벤트 처리기를 올바르게 추가/제거하는 방법에 대한 질문이 있습니다.다중 스레드 응용 프로그램에 대한 이벤트 처리기 추가 및 제거
비 관리 코드에서 콜백을 전달하는 ProxyDLL에서 비동기 콜백을받는 MyCore 클래스가 있습니다. 나는 이벤트를 구독하는 형태 (관리 형)를 가지고있다.
이벤트 연결/제거에 대한 올바른 접근 방법은 무엇입니까? MulticastDelegate에 _invocationcount가 있음을 알았습니다. 그것은 무엇입니까? 콜백 호출이 진행 중일 때 이벤트 콜백이 완료 될 때까지 이벤트의 내부 로직이 이벤트로부터 분리되는 것을 차단합니까? 해당 _ 포유류에 _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);
}
}
}
}
감사합니다. 좋은 지적입니다. 그리고 안전에 관해서 - 당신은 이벤트로부터 청취자를 구독 취소하는 것이 막히는 호출이라고 말하고 싶습니까? – adspx5
@ adspx5 : C# 4.0 이상에서는 Interlocked.CompareExchange를 사용하여 가입 및 가입 취소를 수행합니다. C# 3.0 이하에서는'lock (this)'을 사용합니다. C# 3.0 이하는 잠금이 현재 다른 사람에 의해 유지되는 경우 차단됩니다. –
그것은 내가 이해하려고하는 것이 아닙니다. 이해했지만 호출 목록 변경은 걱정하지 않아도됩니다. 나는 대의원의 일생을 걱정한다. ReleaseCallBackOnLogOn이 탈퇴 대리인을 종료 할 때 콜백이 호출되지 않도록해야합니다. 10 초 동안 내 대리자가 잠자기 상태가되고 그 후에 MyForm :: m_Somevalue가 변경됩니다.콜백 호출이 완전히 완료 될 때까지 클래스 인스턴스가 아직 살아 있는지 확인해야합니다. – adspx5