문제

구현이 스레드-안전보다 낮습니까? 내가 놓친 것이 아니라면? 내가 가야할까요 volatile 어딘가에 키워드? 또는 어딘가에 잠금 OnProcessingCompleted 방법? 그렇다면 어디?

public abstract class ProcessBase : IProcess
{
    private readonly object completedEventLock = new object();

    private event EventHandler<ProcessCompletedEventArgs> ProcessCompleted;

    event EventHandler<ProcessCompletedEventArgs> IProcess.ProcessCompleted
    {
        add
        {
            lock (completedEventLock)
                ProcessCompleted += value;
        }
        remove
        {
            lock (completedEventLock)
                ProcessCompleted -= value;
        }
    }

    protected void OnProcessingCompleted(ProcessCompletedEventArgs e)
    {
        EventHandler<ProcessCompletedEventArgs> handler = ProcessCompleted;
        if (handler != null)
            handler(this, e);
    }
}

메모: 개인 이벤트와 명시 적 인터페이스를 가진 이유는 추상적 인 기본 클래스이기 때문입니다. 그리고 상속 된 수업은 해당 이벤트와 직접 아무것도하지 않아야합니다. 클래스 래퍼를 추가하여 더 명확하게 =)

도움이 되었습니까?

해결책

개인이 필요하지 않습니다 ProcessCompleted 회원이 될 수 있습니다 event - 단지 필드 일 수 있습니다. private EventHandler<ProcessCompletedEventArgs> ProcessCompleted; - 클래스 내부에서는 항상 현장으로 바로갑니다. event 어쨌든 물건이 사라집니다.

명시 적 잠금 객체로 보여준 접근 방식은 많이 필드와 같은 이벤트를 갖는 것보다 더 많은 스레드 안전 public event EventHandler<ProcessCompletedEventArgs> ProcessCompleted; - 유일한 차이점은 당신이 "이것"을 잠그지 않는다는 것입니다 (좋은 일입니다 - 당신은 이상적으로 잠그는 것을 피하십시오 this) .. "핸들러 변수"접근법은 올바른 방법이지만 여전히 당신이 알아야 할 부작용.

다른 팁

핸들러를 가져올 때도 잠겨 있어야합니다. 그렇지 않으면 최신 값이 없을 수도 있습니다.

protected void OnProcessingCompleted(ProcessCompletedEventArgs e)
{
    EventHandler<ProcessCompletedEventArgs> handler;
    lock (completedEventLock) 
    {
        handler = ProcessCompleted;
    }
    if (handler != null)
        handler(this, e);
}

이것에 주목하십시오 그렇지 않습니다 우리가 결정한 경주 조건을 방지합니다. 그 다음에 하나의 핸들러가 구독되지 않은. 우리는 그것을 포함하는 멀티 캐스트 대의원을 가져 왔기 때문에 여전히 호출됩니다. handler 변하기 쉬운.

핸들러 자체가 더 이상 부르지 않아야한다는 것을 알리는 것 외에는 이것에 대해 할 수있는 일이 많지 않습니다.

그렇지 않은 것이 틀림없이 낫습니다 노력하다 이벤트를 스레드 - 안전 - 구독이 이벤트를 제기 할 스레드의 변화.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top