Il y a 2 suggestions je ferais donné le code et ce que je suppose est votre conception. Cependant, je tiens à souligner tout d'abord que vous devriez vraiment utiliser, non-blocage I/O rappels lorsque vous travaillez avec des I/O comme réseau ou des systèmes de fichiers. Il est de loin BEAUCOUP plus efficace et que votre application fonctionnera beaucoup mieux si elles sont plus difficiles à programmer. J'aborderai brièvement une suggestion de modification de la conception à la fin.
- Utilisez la fonction(){} pour TcpClient
- Fil de discussion.Abort()
- TcpListener.En attendant()
- Asynchrone de réécriture
Utilisez la fonction(){} pour TcpClient
*** Notez que vous devriez vraiment joignez à votre TcpClient appel à une aide(){} bloc pour s'assurer que TcpClient.Dispose() ou TcpClient.Close() les méthodes sont appelées, même dans le cas d'une exception. Alternativement, vous pouvez mettre ceci dans le bloc finally d'un try {} finally {} bloc.
Fil de discussion.Abort()
Il y a 2 choses que je vois que vous pourriez faire. 1, c'est que si vous avez commencé ce TcpListener fil à partir d'un autre, vous pouvez simplement appeler Fil.Abandon de la méthode d'instance sur le fil qui va provoquer un threadabortexception être jeté dans l'appel de blocage et de marcher jusqu'à la pile.
TcpListener.En attendant()
La deuxième à faible coût solution serait d'utiliser l'auditeur.Dans l'attente de() la méthode à mettre en œuvre un modèle de bureau de vote. Ensuite, vous devez utiliser un Fil.Le sommeil à "attendre" avant de voir si une nouvelle connexion est en attente. Une fois que vous avez une attente de connexion que vous souhaitez appeler AcceptTcpClient et qui libèrent la connexion en attente. Le code devrait ressembler à quelque chose comme ça.
while (listen){
// Step 0: Client connection
if (!listener.Pending())
{
Thread.Sleep(500); // choose a number (in milliseconds) that makes sense
continue; // skip to next iteration of loop
}
TcpClient client = listener.AcceptTcpClient();
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleConnection));
clientThread.Start(client.GetStream());
client.Close();
}
Asynchrone De Réécriture
Enfin, je vous recommande vraiment de passer à un non-blocage de la méthodologie pour votre application. Sous les couvertures le cadre utilisera Overlapped I/O et I/O ports de fin pour mettre en œuvre les non-blocage I/O à partir de vos appels asynchrones. Il n'est pas très difficile, il faut juste penser à votre code un peu différemment.
Fondamentalement, vous commencerez votre code avec le BeginAcceptTcpClient méthode et de garder trace de la IAsyncResult que vous êtes renvoyé. Vous point qu'à une méthode dont le responsable de l'obtention de la TcpClient et la passant PAS pour un nouveau thread, mais à un fil du pool de threads.QueueUserWorkerItem de sorte que vous n'êtes pas en rotation et la fermeture d'un nouveau thread pour chaque demande du client (veuillez Noter que vous devez utiliser votre propre pool de threads si vous avez particulièrement longtemps vécu les demandes, car le pool de threads est partagé et si vous monopoliser tous les threads d'autres parties de votre application mise en œuvre par le système peut être mis à jeun). Une fois que l'auditeur méthode a débuté votre new TcpClient à son propre pool de threads demande il appelle BeginAcceptTcpClient de nouveau et de points, le délégué de retour à lui-même.
Effectivement, vous êtes juste à la rupture de votre méthode actuelle dans 3 différentes méthodes qui seront ensuite appelés par les différentes parties. 1. pour bootstrapt everythin, 2. d'être la cible d'appeler EndAcceptTcpClient, le coup d'envoi de la TcpClient à son propre thread, puis appeler une fois de plus, de 3. pour traiter la demande du client et de le fermer lorsque vous avez terminé.