2012-02-16 3 views
3

SocketAsyncEventArgs를 사용하여 수백 가지 장비 (대부분 GPRS를 통해)와 통신합니다. 경우에 따라 일부 사용자가 응답을 중지하고 시간 제한 옵션 (예 : SocketOptionName.SendTimeout)이 비동기 통신에 작동하지 않는다고 문서에 명시되어 있으므로 작업 시간 초과 방법이없는 것으로 보입니다.SocketAsyncEventArgs와의 비동기 소켓 통신 시간 초과

보내기/받기/ConnectAsync를 할 때 시간 초과 확인 방법을 찾고 있습니다. 그것은 thread를 막아서는 안된다. someMonitor.WaitOne (SomeTimeoutValue)를 호출하면 안된다.) 그리고 작업 당 타이머 인스턴스를 생성하고 싶지는 않다.

이것에 대한 도움말?

+0

어떤 전송 프로토콜을 사용하고 있습니까? 어쩌면 이미 문제를 해결하는 [UDPClient] (http://msdn.microsoft.com/en-us/library/system.net.sockets.udpclient.aspx) 또는 TCP 클래스와 같은 래퍼 클래스가 있습니까? – HaMster

답변

2

여기에 (내가 솔루션을 좋아하지 않았다 입력해도) 어떻게 내가 해냈어 :

생각은 발사 할 때, 시간 제한에 대한 모든 보류중인 작업을 확인, 하나의 타이머를하는 것입니다. 비동기 작업을 시작할 때

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

때문에, 클라이언트가 Begin 이벤트를 발생하고을 제기

가 작동이 열거는,로 정의된다
public interface ITimeoutable { 
    event Action<ITimeoutable, Operation> Begin; 
    event Action<ITimeoutable, Operation> End; 
    void DoTimeout(Operation operation); 
} 

가 : 나는 나의 비동기 클라이언트가 구현하는 인터페이스를 생성 End 이벤트가 끝나면. 다른면에서 비동기 클라이언트 컬렉션과 작업이있는 사전 및 시작된 순간이있는 TimeoutManager를 만들었습니다. 새 클라이언트가 생성되면 이벤트를 구독하는 TimeoutManager에 등록됩니다. TimeoutManagerSystem.Threading.Timer을 사용하여 어떤 작업 시간이 초과되었는지 확인합니다. 시간 초과가있는 경우 DoTimeout 메소드 (ITimeoutable 인터페이스에서)를 호출합니다.

상당히 복잡한 코드이며 마음에 들지 않습니다. 그러나 그것은 효과적이다.