惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
J
Java Code Geeks
雷峰网
雷峰网
WordPress大学
WordPress大学
宝玉的分享
宝玉的分享
云风的 BLOG
云风的 BLOG
V
Visual Studio Blog
V
Vulnerabilities – Threatpost
S
Securelist
The Hacker News
The Hacker News
The Register - Security
The Register - Security
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Help Net Security
Help Net Security
G
Google Developers Blog
Hugging Face - Blog
Hugging Face - Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
M
MIT News - Artificial intelligence
AI
AI
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
The GitHub Blog
The GitHub Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Schneier on Security
Schneier on Security
N
Netflix TechBlog - Medium
T
The Blog of Author Tim Ferriss
Google DeepMind News
Google DeepMind News
Hacker News - Newest:
Hacker News - Newest: "LLM"
H
Hacker News: Front Page
博客园 - 司徒正美
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
B
Blog
Microsoft Azure Blog
Microsoft Azure Blog
大猫的无限游戏
大猫的无限游戏
Security Latest
Security Latest
Engineering at Meta
Engineering at Meta
N
News and Events Feed by Topic
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
酷 壳 – CoolShell
酷 壳 – CoolShell
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
Threat Research - Cisco Blogs
U
Unit 42
V
V2EX
V2EX - 技术
V2EX - 技术
L
LINUX DO - 最新话题
aimingoo的专栏
aimingoo的专栏
Microsoft Security Blog
Microsoft Security Blog
Recorded Future
Recorded Future
P
Privacy & Cybersecurity Law Blog
美团技术团队
小众软件
小众软件
F
Fortinet All Blogs

博客园 - idior

每日代码 - 7/1 减小方法参数的依赖 每日代码 - 6/29 读写分离 每日代码 - 6/28 代码逻辑分组 每日代码 - 6/26 lambda表达式 每日代码 - 6/27 避免创建非法对象 Resume Covariance and Contravariance How does ElementName Binding work? Weird behavior of DataContext Inheritance How does ElementName Binding work – Part 3 InheritanceContext How does ElementName Binding work – Part 2 BindingExpression Logical Tree & Visual Tree Resources on Debugging/Tracing WPF How does ElementName Binding work? - Part 1 Logical Tree & NameScope Inside WCF Runtime 有谁准备参加10月份的MVP聚会? MVP聚会 Practical .NET2 and C#2 翻译样章 Be evil or not?
Memory leak caused by EventHandle - weak event
idior · 2010-06-04 · via 博客园 - idior

When using normal C# events, registering an event handler creates a strong reference from the event source to the listening object.

If the source object has a longer lifetime than the listener, and the listener doesn't need the events anymore when there are no other references to it, using normal .NET events causes a memory leak: the source object holds listener objects in memory that should be garbage collected.

An article in codeproject provides various patterns for resolving the memory leak caused eventhandle.

1.  Dispose pattern. Unhook the event handler in dispose method.

Disadvantages: Explicit memory management is hard, code can forget to call Dispose.

2.    Use an event wrapper.

This solution moves the event handling code into a wrapper class that forwards the calls to a listener instance which is referenced with a weak reference. This weak reference allows for easy detection if the listener is still alive.

Disadvantages : Leaks the wrapper instance when the event never fires.

3.      WPF WeakEventManager.

WPF has built-in support for listener-side weak events, using the WeakEventManager class. It works similar to the previous wrapper solutions, except that a single WeakEventManager instance serves as a wrapper between multiple sender and multiple listeners. Due to this single instance, the WeakEventManager can avoid the leak when the event is never called: registering another event on a WeakEventManager can trigger a clean-up of old events. These clean-ups are scheduled using the WPF dispatcher, they will occur only on threads running a WPF message loop. 

Also, the WeakEventManager has a restriction that our previous solutions didn't have: it requires the sender parameter to be set correctly, otherwise the source cannot be found in the listener's code.

Disadvantages: Tied to a WPF dispatcher, cannot be easily used on non-UI-threads.

A long thread in WPF-Disciples holds a discussion on a potential bug in RelayCommand. Nathan Nesbit though WPF’s CanExecuteChanged Implementation was Wrong.

The RelayCommand directly registers the CanExecuteChanged event handler with the CommandManager.RequestSuggested event.  The MSDN docs say that the CommandManager.RequestSuggested only holds a weak reference to the handler, so shouldn't the RelayCommand also keep a strong reference to the delegate to avoid it being collected?   

The answer is that we should either keep a strong reference to the delegate on Command Source or Listener. WPF keeps the delegate on Command Source which are Button, MenuItem and etc.

Check out the second line of HookCommand method which defined in ButtonBase:

代码

private void HookCommand(ICommand command)
{
    EventHandler handler = new EventHandler(this.OnCanExecuteChanged);
    CanExecuteChangedHandler.SetValue(this, handler);
    command.CanExecuteChanged += handler;
    
this.UpdateCanExecute();
}

Delay's blog talks about how to use SOS and gcroot to diagnose memory leak.

招聘广告,道富信息科技和网新恒天都招聘.NET高级开发人员和架构师。需要对.NET和面向对象设计有比较深入的了解和较好的英文读写能力,如果有 WPF 或Silverlight开发经验更佳,工作地点杭州。简历请发至 nxu  [at] statestreet [dot] com。