2011-05-12 7 views
6

मेरे पास एक कोड है जो क्लाइंट को संदेश भेजने और उससे प्रतिक्रिया की अपेक्षा करने के लिए एसिंक सॉकेट का उपयोग कर रहा है। यदि ग्राहक ने निर्दिष्ट आंतरिक में जवाब नहीं दिया है तो यह टाइमआउट पर विचार करेगा। इंटरनेट में से कुछ लेख WaitOne का उपयोग करने का सुझाव देते हैं, लेकिन यह थ्रेड को अवरुद्ध करेगा और I/O पूर्णता का उपयोग करने के उद्देश्य को रोक देगा।Async सॉकेट में टाइमआउट कैसे संभालें?

एसिंक सॉकेट में टाइमआउट को संभालने का सबसे अच्छा तरीका क्या है?

Sub OnSend(ByVal ar As IAsyncResult) 
     Dim socket As Socket = CType(ar.AsyncState ,Socket) 
     socket.EndSend(ar) 

     socket.BeginReceive(Me.ReceiveBuffer, 0, Me.ReceiveBuffer.Length, SocketFlags.None, New AsyncCallback(AddressOf OnReceive), socket) 

End Sub 

उत्तर

6

आप समय-समाप्त या अतुल्यकालिक Socket कार्यवाही रद्द नहीं कर सकते। अपनी खुद की Timer जो Socket -इस कॉलबैक तो तुरंत बुलाया जाएगा और EndX समारोह वापस एक ObjectDisposedException साथ आ जाएगा अगर आप इसे फोन बंद कर देता है

आपको बस इतना कर सकते हैं शुरू है। यहां एक उदाहरण दिया गया है:

using System; 
using System.Threading; 
using System.Net.Sockets; 

class AsyncClass 
{ 
    Socket sock; 
    Timer timer; 
    byte[] buffer; 
    int timeoutflag; 

    public AsyncClass() 
    { 
      sock = new Socket(AddressFamily.InterNetwork, 
       SocketType.Stream, 
       ProtocolType.Tcp); 

      buffer = new byte[256]; 
    } 

    public void StartReceive() 
    { 
      IAsyncResult res = sock.BeginReceive(buffer, 0, buffer.Length, 
       SocketFlags.None, OnReceive, null); 

      if(!res.IsCompleted) 
      { 
       timer = new Timer(OnTimer, null, 1000, Timeout.Infinite); 
      } 
    } 

    void OnReceive(IAsyncResult res) 
    { 
      if(Interlocked.CompareExchange(ref timeoutflag, 1, 0) != 0) 
      { 
       // the flag was set elsewhere, so return immediately. 
       return; 
      } 

      // we set the flag to 1, indicating it was completed. 

      if(timer != null) 
      { 
       // stop the timer from firing. 
       timer.Dispose(); 
      } 

      // process the read. 

      int len = sock.EndReceive(res); 
    } 

    void OnTimer(object obj) 
    { 
      if(Interlocked.CompareExchange(ref timeoutflag, 2, 0) != 0) 
      { 
       // the flag was set elsewhere, so return immediately. 
       return; 
      } 

      // we set the flag to 2, indicating a timeout was hit. 

      timer.Dispose(); 
      sock.Close(); // closing the Socket cancels the async operation. 
    } 
} 
+1

मुझे एक समान उत्तर मिला। http://stackoverflow.com/questions/1231816/net-async-socket-timeout-check-thread-safety। विचार यह है कि जांच के लिए सभी मौजूदा कनेक्शन की देखभाल करने के लिए एक टाइमर होना टाइमआउट है। – kevin