【问题标题】:What happen when event is unsubscribe before subscribe it in C#?在 C# 中订阅之前取消订阅事件会发生什么?
【发布时间】:2020-01-01 14:06:45
【问题描述】:

在订阅之前取消订阅事件究竟会发生什么。 在代码级别,它不会抛出任何异常,而是他们处理这种情况的具体核心逻辑是什么。

try
{
    // function (which may throw exception)
    doWork();

    // Subscribe event
    _test.MyEvent += MyEventHandler;

    // other code
}
catch (Exception)
{
     // do error handling
}
finally
{
     // Unsubscribe event
    test.MyEvent -= MyEventHandler;
}

如果 doWork() 函数抛出异常,那么最终会发生取消订阅。关于这一点,处理这种情况的最佳解决方案是什么。

这种情况在退订前借助bool变量判断是否更好。

或者

不检查就可以取消订阅事件,因为它不会抛出任何异常。

【问题讨论】:

  • 事件作为 Windows Timer Tick 事件处理程序的一部分进行处理,该处理程序具有要处理的事件列表。当一个新事件发生时,它被放在一个要处理的事件列表中。然后windows查看要处理的事件列表并找到为事件注册的第一个进程。如果没有人注册事件窗口,则从列表中删除该事件并继续,这样就不会发生任何事情。所以你的答案是什么。
  • 表示事件未订阅,因此不会添加到事件列表中,因此当尝试取消订阅时,它不存在于事件列表中,因此会跳过。所以这不是有害的操作。
  • 没有。如果您有一个计时器并且计时器仍在运行,它会将项目放入队列中。取消订阅只是停止调用事件处理程序,因为注册正在将计时器事件移动到事件处理程序。
  • @jdweng 这里没有特定于 Windows、计时器或队列的内容。事件只是添加/删除代表的一种方式。通常它们被放置在一个列表中,然后由暴露事件的类中的方法调用。所有这些都是同步的,与队列、定时器等无关。
  • @Daniel Earwicker:你错了。您不了解 windows 中发生的事情和网络代码中发生的事情之间的关系。

标签: c# winforms events


【解决方案1】:

这取决于事件的实现方式。在 C# 中,我们可以使用自定义 addremove 逻辑声明一个事件。 add 的实现者可以随心所欲地存储提供的委托。

如果他们认为这将有助于标记对他们班级的滥用,他们理论上也可以从remove 内部throw。但在大多数情况下,这将是令人惊讶的行为,因为(正如您所观察到的)事件上的-= 通常可以容忍误用。

自定义访问器的全部意义在于改变通常的行为,但遵循最小意外原则是一件好事。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-08
    • 2019-12-30
    相关资源
    最近更新 更多