当发布者和处理者是同一个对象时,我应该取消订阅事件吗?
Should I unsubscribe from events when publisher and handler are the same object?
已经有几个问题与此类似:this and this
我特别引用了 Marc Gravell 的回答 (here):
If you have A publishing an event, and B subscribing to an event (the handler), then it is only a problem not to unsubscribe if A is going to live a lot longer than B.
但是当事件源和处理程序是相同的引用时,我找不到任何提及的特殊情况,例如:
class Foo
{
public event Action SomeEvent;
public Foo() => SomeEvent += OnSomeEventHappened; //should I unsubscribe somewhere?
private void OnSomeEventHappened(){}
}
我只是想确定上面的代码没有隐藏的问题。据我所知,我可能永远不会取消订阅该事件,因为订阅者和发布者都是完全相同的实例。
不订阅会阻止我的 Foo 实例被垃圾回收吗?
这似乎没有必要。
根据您的评论,听起来您最担心垃圾收集(或可能缺乏垃圾收集)。
我刚刚受 this answer 启发编写了一个超级快速测试应用程序,以测试对象是否被垃圾收集。它似乎是。
这是我用来测试的代码(运行 在 Release 中),使用与 Foo
class 相同的代码(为简单起见省略):
class Program
{
[STAThread]
static void Main()
{
Foo foo = new Foo();
WeakReference fooRef = new WeakReference(foo);
Console.WriteLine(fooRef.IsAlive); //Displays "True"
foo = null;
GC.Collect();
Console.WriteLine(fooRef.IsAlive); //Displays "False"
Console.ReadKey();
}
}
输出:
True
False
Here's a fiddle 似乎也能完成这项工作(假设它没有自己的垃圾收集怪癖......我不是一个超级有经验的 "fiddler")。
已经有几个问题与此类似:this and this
我特别引用了 Marc Gravell 的回答 (here):
If you have A publishing an event, and B subscribing to an event (the handler), then it is only a problem not to unsubscribe if A is going to live a lot longer than B.
但是当事件源和处理程序是相同的引用时,我找不到任何提及的特殊情况,例如:
class Foo
{
public event Action SomeEvent;
public Foo() => SomeEvent += OnSomeEventHappened; //should I unsubscribe somewhere?
private void OnSomeEventHappened(){}
}
我只是想确定上面的代码没有隐藏的问题。据我所知,我可能永远不会取消订阅该事件,因为订阅者和发布者都是完全相同的实例。
不订阅会阻止我的 Foo 实例被垃圾回收吗?
这似乎没有必要。
根据您的评论,听起来您最担心垃圾收集(或可能缺乏垃圾收集)。
我刚刚受 this answer 启发编写了一个超级快速测试应用程序,以测试对象是否被垃圾收集。它似乎是。
这是我用来测试的代码(运行 在 Release 中),使用与 Foo
class 相同的代码(为简单起见省略):
class Program
{
[STAThread]
static void Main()
{
Foo foo = new Foo();
WeakReference fooRef = new WeakReference(foo);
Console.WriteLine(fooRef.IsAlive); //Displays "True"
foo = null;
GC.Collect();
Console.WriteLine(fooRef.IsAlive); //Displays "False"
Console.ReadKey();
}
}
输出:
True
False
Here's a fiddle 似乎也能完成这项工作(假设它没有自己的垃圾收集怪癖......我不是一个超级有经验的 "fiddler")。