3

I am writing a .NET library. One of the classes has events a user of the library will need to subscribe to. Is it OK to ask implementations of handlers for these events return quickly? Or is this a common problem for which there is a common solution?

(It will no be fatal if the handler took long - but things start to wrong if their handler takes longer than about half a second - it is a networking library and peers connected will think this peer has dropped as the event is raised on the same thread for sending replies)

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...
    }
}
markmnl
  • 11,116
  • 8
  • 73
  • 109
  • 1
    I guess the real question is, what are your other options? – user541686 Dec 02 '13 at 11:13
  • I guess could BeginInvoke() it on another thread (a thread pool one perhaps), or I could stash the event and have the client periodically poll for events that have happened already.. – markmnl Dec 02 '13 at 11:15
  • Looks like a thread pool would work here. Though I didn't understand how this network library work. If that is some public API then why not use wcf and let it manage remote calls? – Artyom Dec 02 '13 at 11:19
  • @Artjom yes - but perhaps it is asking more the user to now write thread safe code! There are many reasons why I am not using WCF, which I don't care elaborate on! – markmnl Dec 02 '13 at 11:21
  • I'm reminded of the situation with Windows, which switched from [Cooperative multitasking](http://en.wikipedia.org/wiki/Computer_multitasking#Cooperative_multitasking.2Ftime-sharing) to [Pre-emptive multitasking](http://en.wikipedia.org/wiki/Computer_multitasking#Preemptive_multitasking.2Ftime-sharing) because, well, developers weren't good at playing well with others... – AakashM Dec 02 '13 at 11:27
  • Well you can ask, if they like you they might even comply. I'd be looking at an asynchronous scheme though – Tony Hopkinson Dec 02 '13 at 11:29

3 Answers3

4

Is it OK to ask handlers of my events return immediately?

Yes.

You should explicitly state in your documentation that the library will not work well if the subscribers do not return in a timely fashion.

You should not enforce it

Why? Because you are saying that you are developing a library. A library, as opposed to a framework, leaves the user in control. Hence it's the user decision to do what they want when they subscribe upon your events.

Enforcing handlers to be quick would just increase the complexity making the library harder to use. That's why I think it's better to be clear with the expectations and just refer the users to the documentation if they get problems thanks to their slow handlers.

jgauffin
  • 99,844
  • 45
  • 235
  • 372
2

If it is crucial for your code that the handlers return quickly, you should build it upon a structure that allows you to cancel a handler. As event handlers do not allow you to cancel the execution of a handler, e.g. by a timeout, you have the following options among others:

  • Use event handlers and accept that you do not have any control about what the caller does. Of course you can ask the callers to return within a specific time frame, but you should be prepared that sometimes they will not. You could, however, structure your code so that the event handlers are called at a spot in your code that is not time critical (e.g. in your sample move "Time important stuff" in front of the raise) or use threads to allow for parallel execution.
  • If you do not need the special characteristics of events (e.g. subscription model, subscription of multiple handlers), you can use an alternative approach that allows you to cancel the handler. Depending on the Framework version you use, an alternative might be to use a Task that a caller provides to your class similar to a callback function. Tasks allow you to Wait for a specific number of milliseconds for their completion.
Markus
  • 20,838
  • 4
  • 31
  • 55
  • I have marked the "yes it is OK" as the answer as I thought this is what MS does, e.g. in event based UI where handlers are invoked synchronously on the UI thread and expected to return quickly. Nonetheless you have shown valid alternative approaches worth considering depending on ones scenario - wish I could mark it as the answer too! – markmnl Dec 31 '13 at 04:47
0

Personally I think it is a bad idea - since Windows is not real-time operation system. In non real-time operation systems you can't count on some method executing 0.5 seconds.

nikita
  • 2,737
  • 2
  • 20
  • 26
  • 0.5 seconds? Where on earth did you get the number? Sounds like something that my first computer would be able to do (IBM XT compatible) – jgauffin Dec 02 '13 at 14:31
  • 0.5 seconds - from topic. Could you guarantee on your IBM that it would take less then 0.5 seconds for your OS to start some thread after some event occurred? If some heavy calculations were taking place at that moment? You can't be sure about that since Windows doesn't schedule tasks\event as real-time OS. Obviously there should be some timeouts but 500ms is more like "real-time" interval. – nikita Dec 02 '13 at 15:10
  • @nikita I am calling the event synchronously, not starting a new thread. Though I would never call 500ms "real-time" you can network packets around the world in that time, easily, I would say a couple microseconds is "real-time", though "real-time" could be any time so long as the max time is always known as a hard and fast value, though this is going off topic... – markmnl Dec 02 '13 at 15:42
  • @nikita though I take your point, the OS could only give my thread CPU time to run anytime in the future, however I have tested and am familiar with what I am doing, this is fast paced application - such a timeout is fine. – markmnl Dec 02 '13 at 15:53