Search code examples
c#.nettimeout

API Design for Timeouts: TimeoutException or boolean return with out parameter?


The scenario is RPC over message queues - since the underlying mechanism is asynchronous, clients should specify how long they want to wait for a response before timing out. As the client, which of these two code snippets would you rather use?

Most importantly: as a user of the GetResponseTo() method, why would you prefer one over the other? How does your choice make your code more extensible, more readable, more testable, etc?

try
{
    IEvent response = _eventMgr.GetResponseTo(myRequest, myTimeSpan);
    // I have my response!
}
catch(TimeoutException te)
{
    // I didn't get a response to 'myRequest' within 'myTimeSpan'
}

OR

IEvent myResponse = null;

if (_eventMgr.GetResponseTo(myRequest, myTimeSpan, out myResponse)
{
    // I got a response!
}
else
{
    // I didn't get a response... :(
}

For your information, here's the current implementation of GetResponseTo():

public IEvent GetResponseTo(IEvent request, TimeSpan timeout)
{
    if (null == request) { throw new ArgumentNullException("request"); }

    // create an interceptor for the request
    IEventInterceptor interceptor = new EventInterceptor(request, timeout);

    // tell the dispatcher to watch for a response to this request
    _eventDispatcher.AddInterceptor(interceptor);

    // send the request
    _queueManager.SendRequest(request);

    // block this thread while we wait for a response.  If the timeout elapses,
    // this will throw a TimeoutException
    interceptor.WaitForResponse();

    // return the intercepted response
    return interceptor.Response;
}

Solution

  • I have elected to use the out parameter.

    I wanted to mark someone else as the answer, but I am not able to do so. I attempted to implement the TPL-based approach, but was unable to do so, based on the question/answer that I linked in my comments.

    I do not want to muddy my event model by introducing even more concepts, as @sll suggests.

    And even though @dasheddot prefers the exception Version, @sll has a good point that someone trying to send a bunch of requests and get a bunch of responses in a loop might have to deal with a lot of exceptions.

    // potentially 10 exceptions?  meh... let's not go down this road.
    for(int i=0;i<10;i++)
    {
      try
      {
         IEvent response = _eventMgr.GetResponseTo(myRequest, myTimeSpan);
    
         // I have my response!
      }
      catch(TimeoutException te)
      {
         // I didn't get a response to 'myRequest' within 'myTimeSpan'
      } 
    }