2013-02-26 19 views
1

我需要刪除系統中每個對象的所有事件綁定。有成千上萬的對象持有事件,這導致內存泄漏。我受到嚴重的時間限制,以獲得這種排序,所以我想知道是否有一種方法遞歸循環通過對象層次結構來刪除事件綁定?如何遞歸遍歷層次結構中的每個對象並刪除所有事件引用?

+0

WinForm的? WPF? Asp.net? Silverlight的?我可以繼續嗎? – gdoron 2013-02-26 16:41:32

+0

C#。自定義對象,自定義事件。 – DaveDev 2013-02-26 16:52:58

+1

看來你有一個很大的問題,需要重寫系統中的所有類。或者放棄你的系統並從場地上寫下新的系統。 – 2013-02-26 17:14:04

回答

0

討厭。除非您知道事件處理程序的名稱,否則它看起來不可能使用反射;是否可以修改對象的Dispose方法以刪除其成員的事件處理程序?

+0

它可能是,但是這將需要大量的代碼修改。我希望有一個快速簡單的方法。不幸的是,這可能不會是其中之一! – DaveDev 2013-02-26 17:11:58

+0

有一種令我驚訝的是沒有(或似乎不是)。 – 2013-02-26 17:12:35

1

注意:這是所有真的哈克東西,我不會寬恕它的用法!

這就是說......是的,你可以。均田。

說你已經有了類Foo

public class Foo 
{ 
    public event EventHandler SomeEvent; 
    public void Trigger() 
    { 
     if(SomeEvent != null) 
     { 
      SomeEvent(this, new EventArgs()); 
     } 
    } 
} 

我們新的這些了一個,並連接到事件中的各種方法:

public class Bar 
{ 
    public Bar(Foo foo) 
    { 
     foo.SomeEvent += FooEvent; 
    } 
    public void FooEvent(object sender, EventArgs e) 
    { 
     Console.WriteLine("Bar.FooEvent!"); 
    } 
} 

var foo = new Foo(); 
var bar = new Bar(foo); 
foo.SomeEvent += (o,e) => Console.WriteLine("SomeEvent"); 

Console.WriteLine("Normal"); 
foo.Trigger(); 

輸出:

Normal 
Bar.FooEvent! 
SomeEvent 

到目前爲止,一切正常嗎?

現在 - 即通過反思是允許的污穢:

首先,我們需要的EventInfo和事件的remove方法參考:

var theFooEvent = foo.GetType().GetEvent("SomeEvent"); 
var theFooRemover = theFooEvent.GetRemoveMethod(true); 

接下來,我們將濫用Expressions一點點來獲得「現值」:

var exp = 
    System.Linq.Expressions.Expression.PropertyOrField(
     System.Linq.Expressions.Expression.Constant(foo), 
     "SomeEvent"); 
var member = exp.Member; 
var rtMember = (member as FieldInfo).GetValue(foo) as EventHandler; 

我們已經半路上 - 現在要吹走所有現有的處理程序:

var handlers = rtMember.GetInvocationList(); 
foreach(var handler in handlers) 
{ 
    theFooRemover.Invoke(foo, new[] { handler }); 
} 

有......就是這樣!到Trigger進一步的調用實際上並不會做任何事情:

Console.WriteLine("Post hackery"); 
foo.Trigger(); 

輸出:

Post hackery