2011-05-12 21 views
6

İstemciye mesaj göndermek ve ondan yanıt beklemek için async soketini kullanan bir kodum var. İstemci belirtilen bir dahili cevap vermediyse, zaman aşımını dikkate alacaktır. İnternetteki makalenin bir kısmı WaitOne'u kullanmasını önermektedir, ancak bu iş parçacığını engelleyecek ve G/Ç tamamlanmasını kullanma amacını ortadan kaldıracaktır.Async Socket'de zaman aşımı nasıl yapılır?

Zaman uyumsuzluğu için zaman uyumsuzluğu yerine getirmenin en iyi yolu nedir?

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 

cevap

6

Zaman uyumsuzluğu veya eşzamanlı olmayan Socket işlemlerini iptal edemezsiniz.

Tek yapabileceğiniz başlangıç ​​olduğunu kendi -the geri arama daha sonra hemen çağrılır Socket ve bunu ararsanız EndX işlev ObjectDisposedException birlikte döneceğine kapatır Timer. İşte bir örnek:

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

Benzer bir yanıt buldum. http://stackoverflow.com/questions/1231816/net-async-socket-timeout-check-thread-safety. Fikir, zaman aşımı olup olmadığını kontrol etmek için mevcut tüm bağlantılara bakmak için tek bir zamanlayıcıya sahip olmaktır. – kevin