使用SocketAsyncEventArgs进行异步套接字通信时的超时问题

4
我正在使用SocketAsyncEventArgs与数百个设备进行通信(其中大部分通过GPRS)。有时,其中一些停止响应,似乎我无法设置操作超时时间。因为文档说明异步通信的超时选项(例如SocketOptionName.SendTimeout)不起作用。

我正在寻找一种在执行Send/Receive/ConnectAsync时检查超时的方法。它不应该阻塞线程(因此,调用someMonitor.WaitOne(SomeTimeoutValue)不会起作用),而且我不希望为每个操作创建一个计时器实例(因为设备数量肯定会增加)。

你有什么建议吗?


你正在使用哪种传输协议?也许有像UDPClient或TCP类这样的包装类已经解决了你的问题? - HaMster
1个回答

2
这是我实现的方法(尽管我不太喜欢这个解决方案):
思路是创建一个定时器,在触发时检查所有待处理操作是否超时。我创建了一个接口,我的异步客户端实现了该接口:
public interface ITimeoutable {
    event Action<ITimeoutable, Operation> Begin;
    event Action<ITimeoutable, Operation> End;
    void DoTimeout(Operation operation);
}

其中Operation是一个枚举类型,定义如下:

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

那么,客户端在启动异步操作时会触发“Begin”事件,完成后会触发“End”事件。另一方面,我创建了一个TimeoutManager,其中包括异步客户端的集合和一个包含操作以及它们启动的时间点的字典。当创建新的客户端时,它会被注册到TimeoutManager中,并订阅事件。TimeoutManager使用System.Threading.Timer来检查哪些操作超时。如果它已经超时,那么就调用ITimeoutable接口中的DoTimeout方法。虽然代码相当复杂,但是它可以正常工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接