2010-10-05 35 views
2

J'ai créé une application Windows à un seul thread qui communique avec plus de 100 sockets (en utilisant AsyncCallbacks), peut être 5-10 sockets en une seconde.Problème avec AsyncCallback dans C# .NET 3.5

L'application fonctionne correctement lorsque je lance depuis .NET IDE. L'application semble être pendu si lancé à partir de l'exécutable. Sur la recherche ultérieure, j'ai trouvé que l'application communique parfaitement sur les sockets, seules les données de l'interface utilisateur ne sont pas actualisées. Il semble que l'application soit trop occupée pour lire depuis les sockets que pour rafraîchir l'interface utilisateur.

L'application fonctionne correctement en remplaçant AsyncCallback par un thread individuel pour chaque socket, mais cela ne semble pas être une bonne approche.

J'ai essayé de créer des files d'attente de messages, mais cela n'a pas aidé. Ai-je raison de dire que l'application est occupée à lire sur le socket plutôt que de rafraîchir l'interface utilisateur? Comment puis-je résoudre ce problème?

Le code que j'utilise pour AsynCallBack est mentionné ci-dessous.

private void ConnectSocket() 
    { 
     IPEndPoint ipEnd = new IPEndPoint(_ip, _port); 
     m_socket = new Socket(ipEnd.AddressFamily, SocketType.Stream, ProtocolType.Tcp); 
     m_socket.Blocking = false; 
     m_socket.ReceiveBufferSize = RECEIVE_BUFFER_SIZE; 
     m_socket.NoDelay = true; 
     m_socket.LingerState = new LingerOption(false, 0); 

     AsyncCallback onconnect = new AsyncCallback(OnConnect); 
     m_socket.BeginConnect(ipEnd, onconnect, m_socket); 
    } 

    private void OnConnect(IAsyncResult ar) 
    { 
     Socket sock = (Socket)ar.AsyncState; 
     try 
     { 
      sock.EndConnect(ar); 
      if (sock.Connected) 
      { 
       SetupReceiveCallback(sock); 
      } 
     } 
     catch (Exception ex) 
     { 
     } 
    } 

    private void SetupReceiveCallback(Socket sock) 
    { 
     try 
     { 
      AsyncCallback receiveData = new AsyncCallback(ReceiveData); 
      sock.BeginReceive(receivedBuffer, 0, receivedBuffer.Length, 
       SocketFlags.None, receiveData, sock); 
     } 
     catch (SocketException ex) 
     { 
     } 
     catch (Exception ex) 
     { 
     } 
    } 

    private void ReceiveData(IAsyncResult ar) 
    { 
     Socket sock = (Socket)ar.AsyncState; 
     try 
     { 
      int numBytesReceived = sock.EndReceive(ar); 

      if (numBytesReceived > 0) 
      { 
       if (OnReceivedData != null) 
       { 
        OnReceivedData(receivedBuffer); 
       } 
      } 
      SetupReceiveCallback(sock); 
     } 
     catch (SocketException ex) 
     { 
      //If error code is 1054 then socket connection is terminated from the client. 
     } 
     catch (Exception ex) 
     { 
     } 
    } 
+0

Nous aurons besoin de voir du code. –

Répondre

1

Il serait très étrange pour l'application d'être débordés, il se fige. Qu'est-ce qui appelle la fonction ConnectSocket()? Si cela est appelé sur un événement d'interface utilisateur (par exemple, lorsqu'un bouton est enfoncé), il sera exécuté sur le thread d'interface utilisateur et l'interface utilisateur se verrouillera jusqu'à ce qu'il soit terminé. Vous devrez déclencher un thread séparé en arrière-plan pour gérer les connexions si vous souhaitez que votre interface utilisateur continue à fonctionner.

Vous pouvez utiliser la classe ThreadPool pour déclencher des threads d'arrière-plan pour gérer les connexions.