Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.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_Design Patterns_Event Handling - Fatal编程技术网

C# 要求我的事件处理程序立即返回可以吗?

C# 要求我的事件处理程序立即返回可以吗?,c#,.net,events,design-patterns,event-handling,C#,.net,Events,Design Patterns,Event Handling,我正在写一个.NET图书馆。其中一个类包含库用户需要订阅的事件。要求这些事件处理程序的实现快速返回可以吗?或者这是一个有共同解决方案的共同问题 (如果处理程序花费很长时间,这不会是致命的-但是如果处理程序花费的时间超过半秒,事情就会开始出错-这是一个网络库,连接的对等方会认为此对等方已放弃,因为在发送回复的同一线程上引发事件) e、 g 公共委托无效Ping(); 甲级 { /// ///如果你的主人不快点回来……我会哭的。 /// 公众活动-平安; 私人募捐 { var=Ping; if(

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

(如果处理程序花费很长时间,这不会是致命的-但是如果处理程序花费的时间超过半秒,事情就会开始出错-这是一个网络库,连接的对等方会认为此对等方已放弃,因为在发送回复的同一线程上引发事件)

e、 g

公共委托无效Ping();
甲级
{
/// 
///如果你的主人不快点回来……我会哭的。
/// 
公众活动-平安;
私人募捐
{
var=Ping;
if(处理程序!=null)
handler();
}
//这被称为几次一秒
私有void MainLoop()
{
如果(某物)
提升();
//时间很重要-不需要很长时间就能到达这里。。。
}
}

如果处理程序快速返回对代码至关重要,则应将其构建在允许取消处理程序的结构上。由于事件处理程序不允许您取消处理程序的执行(例如,通过超时),因此您有以下选项:

  • 使用事件处理程序并接受您对调用方的操作没有任何控制权。当然,你可以要求打电话的人在特定的时间范围内返回,但你应该做好准备,有时他们不会。但是,您可以对代码进行结构化,以便在代码中非时间关键的位置调用事件处理程序(例如,在示例中,将“时间重要的东西”移到raise之前),或者使用线程来允许并行执行
  • 如果您不需要事件的特殊特征(例如,订阅模型、多个处理程序的订阅),则可以使用允许取消处理程序的替代方法。根据您使用的框架版本,另一种方法可能是使用调用者向类提供的类似于回调函数的函数。任务允许您在特定的毫秒数内完成任务
要求我的事件处理程序立即返回可以吗

您应该在文档中明确说明,如果订阅者不及时返回,库将无法正常工作

您不应该强制执行它

为什么??因为你说你正在开发一个图书馆。与框架相反,库由用户控制。因此,用户决定在订阅您的活动时做他们想做的事情


强制处理程序变得快速只会增加复杂性,使库更难使用。这就是为什么我认为最好明确预期,如果用户由于处理速度慢而遇到问题,请参阅文档。

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

我想真正的问题是,你还有什么其他选择?我想你可以在另一个线程上启动它(可能是一个线程池),或者我可以隐藏事件,让客户端定期轮询已经发生的事件。看起来线程池可以在这里工作。虽然我不明白这个网络图书馆是如何工作的。如果这是一些公共API,那么为什么不使用wcf并让它管理远程调用呢?@Artjom是的-但也许它要求更多用户现在编写线程安全代码!我不使用WCF的原因有很多,我不想详细说明!我想起了Windows的情况,它从切换到是因为,开发人员不善于与其他人玩得很好…0.5秒?你到底从哪里得到这个号码的?听起来像是我的第一台计算机能够在0.5秒内完成的事情(与IBM XT兼容)——从主题开始。您能否在IBM上保证,在某个事件发生后,操作系统启动某个线程所需的时间少于0.5秒?如果在那一刻发生了一些重大的计算?您不能确定这一点,因为Windows没有将tasks\event安排为实时操作系统。显然应该有一些超时,但500毫秒更像是“实时”间隔。@nikita我是同步调用事件,而不是启动新线程。虽然我永远不会称500毫秒为“实时”,但在那个时候,你可以在世界各地联网,很容易,我会说几微秒就是“实时”,尽管“实时”可以是任何时间,只要最大时间始终被认为是一个硬而快的值,尽管这偏离了主题…@nikita尽管我同意你的观点,操作系统只能给我的线程CPU时间在将来的任何时候运行,但是我已经测试并熟悉我正在做的事情,这是一个快节奏的应用程序-这样的超时是可以的。我已经标记了“是的,它是可以的”作为答案,因为我认为这是MS所做的,例如,在基于事件的UI中,处理程序在UI线程上同步调用,并期望快速返回。尽管如此,根据不同的场景,您已经展示了值得考虑的有效替代方法-希望我也能将其标记为答案!
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...
    }
}