Search code examples
c#socketsasynchronoustimeoutsocketasynceventargs

Timeouts on async socket communication with SocketAsyncEventArgs


I'm using SocketAsyncEventArgs to communicate with hundreds of equipments (most of them through GPRS). Sometimes, some of them stop responding and it seems I have no way of timing out the operation, as the documentation states that the timeout options (i.e SocketOptionName.SendTimeout) doesn't work on asynchronous communication.

I'm looking for a way of check for timeouts when doing Send/Receive/ConnectAsync. It should not block the thread (so, calling someMonitor.WaitOne(SomeTimeoutValue) won't do) and I don't want to create a timer instance per operation (as the number of equipments will surely increase).

Any tips on this?


Solution

  • Here's how I did it (altough I didn't like the solution):

    the idea is to have one timer that, when fired, checks all the pending operations for timeouts. I created an interface that my async client implements:

    public interface ITimeoutable {
        event Action<ITimeoutable, Operation> Begin;
        event Action<ITimeoutable, Operation> End;
        void DoTimeout(Operation operation);
    }
    

    where Operation is an enum, defined as:

    public enum Operation {
        Connect,
        Send,
        Receive,
        Disconnect
    }
    

    so, the client raises a Begin event when starting an async operation and raises the End event when finishes it. On the other side, I've created a TimeoutManager, which has a collection of async clients and a dictionary with the operations and the instant they were started. When a new client is created, it is registered into the TimeoutManager, which subscribes to the events. The TimeoutManager uses a System.Threading.Timer to check which operations timed out. If it has a timeout, then it calls the DoTimeout method (from the ITimeoutable interface).

    It is a fairly complex code, and I don't like it. But it works.