4

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?

Fernando
  • 4,029
  • 1
  • 26
  • 35
  • Which transport protocol are you using? Maybe there is a wrapper class like [UDPClient](http://msdn.microsoft.com/en-us/library/system.net.sockets.udpclient.aspx) or TCP classes that already solve your problem? – HaMster Aug 18 '13 at 17:20

1 Answers1

2

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.

Fernando
  • 4,029
  • 1
  • 26
  • 35