2010-06-02 2 views
2

EventAgregator 패턴을 사용하여 이벤트를 구독하고 게시합니다. 사용자가 람다 식을 사용하여 이벤트에 가입하면 약한 참조가 아닌 강력한 참조를 사용해야합니다. 그렇지 않으면 게시가 실행되기 전에 표현식을 가비지 수집 할 수 있습니다.액션이 람다 식인지 어떻게 알 수 있습니까?

간단한 테스트를 DelegateReference에 추가하여 프로그래머가 람다 식을 전달하고 약한 참조를 사용하는 경우 인수 예외를 throw하도록했습니다. 이것은 코드를 "폴링 (police)"하는 것을 돕기위한 것입니다.

예 :

eventAggregator.GetEvent<RuleScheduler.JobExecutedEvent>().Subscribe 
     (
      e => resetEvent.Set(), 
      ThreadOption.PublisherThread, 
      false, 
      // filter event, only interested in the job that this object started 
      e => e.Value1.JobDetail.Name == jobName 
     ); 


public DelegateReference(Delegate @delegate, bool keepReferenceAlive) 
    { 
     if (@delegate == null) 
      throw new ArgumentNullException("delegate"); 

     if (keepReferenceAlive) 
     { 
      this._delegate = @delegate; 
     } 
     else 
     { 
      //TODO: throw exception if target is a lambda expression 
      _weakReference = new WeakReference(@delegate.Target); 
      _method = @delegate.Method; 
      _delegateType = @delegate.GetType(); 
     } 
    } 

어떤 아이디어가? @ delegate.Method.IsStatic을 확인할 수 있다고 생각했지만 작동하지 않습니다 ... (모든 람다식이 정적입니까?)

답변

1

아니요, 모든 람다 생성 대리자가 정적 메서드는 아닙니다. 캡처 된 변수가있는 경우 인스턴스가 될 수 있습니다. 그러나 궁극적으로 람다 기반 대리자, 익명 메서드 기반 대리자 및 명시 적 대리자 간에는 거의 차이가 없습니다. 나는 어떤 추가적인 로직도하지 않을 것입니다. 그냥 위임자로 취급하십시오 (나는 WeakReference 코드를 완전히 제거 할 것입니다).

+0

그래서 대표자가 익명인지 여부를 알 수있는 방법이 있습니까? 개인적으로, WeakReference 코드가 마음에 들지 않습니다. 클래스 수명이 다 된 후에 구독을 취소하지 않으면 백그라운드에서 반복적으로 (또는 적어도 필터 메서드) 호출 될 수 있습니다. 그러나 마이크로 소프트의 "베스트 프랙티스 (Best Practices)"와 같은 것입니다. :) 익명의 대리자와 약한 참조를 사용하려고하면이 패턴을 사용하는 silverlight가 예외를 throw합니다 ... 그래서 나는 그것이 가능해야한다고 생각했습니다. – Keith

+0

@Keith - '새'가 최적화 된 경우 놀랄 것입니다. –

관련 문제