2012-01-16 3 views
7

WeakEventManager를 사용하여 정적 이벤트에 약한 이벤트 수신기를 만들 수 있습니까?정적 이벤트가있는 WeakEventManager 사용

약한 이벤트 리스너를 정적 CompositionTarget.Rendering 이벤트에 만들어서 WPF/Silverlight 소스 요소의 수명을 모르는 경우 메모리 누수를 방지하고 싶습니다.

public class RenderingEventManager : WeakEventManager 
{ 
    public static void AddListener(IWeakEventListener listener) 
    { 
     CurrentManager.ProtectedAddListener(null, listener); 
    } 

    public static void RemoveListener(IWeakEventListener listener) 
    { 
     CurrentManager.ProtectedRemoveListener(null, listener); 
    } 

    private static RenderingEventManager CurrentManager 
    { 
     get 
     { 
      var managerType = typeof(RenderingEventManager); 
      var manager = (RenderingEventManager)GetCurrentManager(managerType); 
      if (manager == null) 
      { 
       manager = new RenderingEventManager(); 
       SetCurrentManager(managerType, manager); 
      } 
      return manager; 
     } 
    } 

    protected sealed override void StartListening(object source) 
    { 
     CompositionTarget.Rendering += this.OnCompositionTargetRendering; 
    } 

    protected sealed override void StopListening(object source) 
    { 
     CompositionTarget.Rendering -= this.OnCompositionTargetRendering; 
    } 

    void OnCompositionTargetRendering(object sender, EventArgs e) 
    { 
     this.DeliverEvent(sender, e); 
    } 
} 

을 간단한 창에서 관리자를 테스트 :

은 내가 weak event pattern에 의해 렌더링 이벤트 관리자를 구현
public partial class Window1 : Window, IWeakEventListener 
{ 
    public Window1() 
    { 
     InitializeComponent(); 
     RenderingEventManager.AddListener(this); 
    } 

    bool IWeakEventListener.ReceiveWeakEvent(Type managerType, object sender, EventArgs e) 
    { 
     return true; 
    } 
} 

가 ReceiveWeakEvent 방법은

호출되지 않습니다. OnCompositionTargetRendering가 호출되었지만 예상대로 DeliverEvent가 작동하지 않는 것 같습니다. Button.Click과 같은 인스턴스 이벤트에 리스너를 추가하면 ... 테스트 프로젝트는 .NET 4.0 Client Profile에 있습니다.

A post on Microsoft Connect from 2009

정적 이벤트가 지원되지 않습니다, 하지만 난 WeakEventManager 소스 코드를 확인한다고, 그리고 그것을 확인 같습니다에 DeliverEvent 방법의 보낸 사람 인수를 변경 :

protected void ProtectedAddListener(object source, IWeakEventListener listener) 
    { 
     Debug.Assert(listener != null, "Listener cannot be null"); 

     object sourceKey = (source != null) ? source : StaticSource; 
     ... 
    } 

답변

7

자신이 그것을 알아 냈어 null :

void OnCompositionTargetRendering(object sender, EventArgs e) 
{ 
    this.DeliverEvent(null, e); 
}