请问处理程序我的事件立即返回是否可以?

时间:2013-12-02 11:02:20

标签: c# .net events design-patterns event-handling

我正在编写一个.NET库。其中一个类具有库的用户需要订阅的事件。是否可以要求处理程序实现这些事件快速返回?或者这是一个常见问题,有一个共同的解决方案吗?

(如果处理程序需要很长时间也不会致命 - 但是如果处理程序需要的时间超过半秒,那么事情就会开始出错 - 它是一个网络库,并且连接的对等体会认为这个对等体已经因为事件被提升而丢失了在发送回复的同一个帖子上)

e.g。

public delegate void Ping();

class A
{
    /// <summary>
    /// If your handler doesn't return quickly... I am going to cry.
    /// </summary>
    public event Ping Ping;

    private void RaisePing() 
    {
         var handler = Ping;
         if(handler != null)
             handler();
    }

    // this is called several times a secound
    private void MainLoop()
    {
        if(something)
            RaisePing();

        // time important stuff - musn't take long to get here...
    }
}

3 个答案:

答案 0 :(得分:4)

  

请问处理程序我的事件是否立即返回?

是。

如果订阅者没有及时返回,您应该在文档中明确声明库不能正常工作。

您不应强制执行

为什么呢?因为你说你正在开发一个库。与框架相对的库使用户处于控制之下。因此,用户决定在订阅您的活动时做他们想要的事情。

快速执行处理程序会增加复杂性,使库更难使用。这就是为什么我认为最好能够清楚地表达期望,如果他们因处理器速度慢而遇到问题,只需将用户引荐到文档中。

答案 1 :(得分:2)

如果处理程序快速返回对您的代码至关重要,则应该在允许您取消处理程序的结构上构建它。由于事件处理程序不允许您取消处理程序的执行,例如如果超时,您可以选择以下选项:

  • 使用事件处理程序并接受您无法控制调用者的操作。当然,您可以要求呼叫者在特定时间范围内返回,但您应该做好准备,有时他们不会。但是,您可以构造代码,以便在代码中的某个位置调用事件处理程序,这对于非时间要求很严格(例如,在示例中移动“时间重要的东西”)或者使用线程来允许并行执行。
  • 如果您不需要事件的特殊特征(例如订阅模型,订阅多个处理程序),您可以使用另一种方法来取消处理程序。根据您使用的Framework版本,另一种方法可能是使用调用者为您的类提供的Task,类似于回调函数。任务允许您Wait完成特定的毫秒数。

答案 2 :(得分:0)

我个人认为这是一个坏主意 - 因为Windows不是实时操作系统。在非实时操作系统中,您不能指望执行0.5秒的某些方法。