Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当对象超出范围时,事件处理程序会发生什么情况?_C#_.net_Events_Scope - Fatal编程技术网

C# 当对象超出范围时,事件处理程序会发生什么情况?

C# 当对象超出范围时,事件处理程序会发生什么情况?,c#,.net,events,scope,C#,.net,Events,Scope,假设我们有以下设置: public class ClassA { public event EventHandler SomeEvent; } public class ClassB : IDisposable { public void SomeMethod(ClassA value) { value.SomeEvent += (s, e) => { DoSomething(); }; } void DoSomething() { }

假设我们有以下设置:

public class ClassA
{
   public event EventHandler SomeEvent;
}

public class ClassB : IDisposable
{
   public void SomeMethod(ClassA value)
   {
      value.SomeEvent += (s, e) => { DoSomething(); };
   }

   void DoSomething() { }

   void Dispose() { }
}

public static class Program
{
   static void Main()
   {
      var a = new ClassA();

      using (var b = new ClassB())
         b.SomeMethod(a);

      // POINT OF QUESTION!!
   }
}

当事件
SomeEvent
在“问题点”之后引发时会发生什么情况?

它将调用disposed object的方法。这就是为什么取消订阅很重要的原因。它甚至可能导致内存泄漏。

您应该使用ClassB的
Dispose()
方法取消订阅ClassA事件。您可能会面临类未被垃圾收集的风险,这当然会导致潜在的内存泄漏。您应该始终取消对事件的跟踪。

上面的任何内容都不会解除事件处理程序的锁定。因为
a
b
同时超出范围,所以您是安全的。由于
a
b
都可以收集,因此
a
将不会使
b
保持活动状态

如果要在using语句之后引发
ClassA.SomeEvent
事件,则即使
b
已被处置,仍将调用
ClassB.DoSomething
。在这种情况下,必须显式删除事件处理程序


如果要在其他地方保留对
a
的引用,则
b
将通过
a
保持活动状态。同样,因为事件处理程序尚未删除。

什么也没有。运行时不知道
Dispose
方法,并在内部使用语句DoNothing to memory management调用此方法


垃圾收集是关于内存管理的,但是IDisposable(和Finalizer)是关于资源管理的,所以你仍然应该考虑自己并手动实现它(并且要适当地,例如在
Dispose
中取消订阅)。

这是C#,.Net吗?我继续添加了这些标签;)这不就是抛出一个运行时错误吗?(空指针引用或类似引用)。@Hogan Disposing不等于被垃圾收集。在这种情况下,
b
将永远不会被垃圾收集,因为在
a
的事件中仍然存在对它的引用(正是问题所在)。如果
b
的实现是正确的,它将抛出一个
ObjectDisposedException
。@Jouke-我想我想知道thunk是否会指向null。我想这是不可能发生的——如果你觉得应该这样做的话。@Hogan只有在Dispose方法正确实现并且取消订阅事件的情况下才会这样做。否则,
b
将不会为空,直到
a
指向的内容被收集(导致
b
也被收集)。