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?
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.