结果是
WeakEventManager
的故障。当触发事件时,它意味着
source
将是
null
对于静态事件源(代码摘录自
reference source
):
protected void DeliverEvent(object sender, EventArgs args)
{
ListenerList list;
object sourceKey = (sender != null) ? sender : StaticSource;
...
但是
sender
永远不会
无效的
对于
SystemEvents
。而是传递
系统事件
,则,
弱势管理者
然后假设它是以前不知道的另一个实例,并且不调用处理程序。
以下是我想到的解决方法:
class EventProxy
{
private readonly Action<EventHandler> _subscribe;
private readonly Action<EventHandler> _unsubscribe;
public EventProxy(Action<EventHandler> subscribe, Action<EventHandler> unsubscribe)
{
_subscribe = subscribe;
_unsubscribe = unsubscribe;
}
private EventHandler _event;
public event EventHandler Event
{
add
{
if (_event == null)
_subscribe(OnEvent);
_event += value;
}
remove
{
// ReSharper disable once DelegateSubtraction
_event -= value;
if (_event == null)
_unsubscribe(OnEvent);
}
}
private void OnEvent(object sender, EventArgs args)
{
_event?.Invoke(this, args);
}
}
用法示例:
var proxy = new EventProxy(h => SystemEvents.DisplaySettingsChanged += h, h => SystemEvents.DisplaySettingsChanged -= h);
WeakEventManager<EventProxy, EventArgs>.AddHandler(proxy, nameof(EventProxy.Event), OnDisplaySettingsChanged);
一些解释:
-
系统事件
强烈引用
EventProxy
,它持有对处理程序的弱引用(通过
弱势管理者
)
-
什么时候
弱势管理者
订阅内部事件
AddHandler
,代理订阅原始事件
-
事件代理
充当静态事件和处理程序之间的代理,在原始事件激发时调用处理程序
-
收集处理程序后,
弱势管理者
将最终运行清理,发现处理程序已死亡并取消订阅
-
这将导致代理从原始事件中取消订阅,并最终由GC收集