5 votes

manière correcte d'abandonner un fil bloqué

Je suis en train de créer un serveur qui a une connexion TCP. La connexion TCP est exécutée dans son propre thread pendant une durée indéterminée. Existe-t-il un bon modèle pour permettre un arrêt sûr du TcpListener et du Client ainsi que du thread ? Voici ce que j'ai fait jusqu'à présent.

private volatile bool Shudown;

void ThreadStart1()
{
    TcpListener listener = null;
    TcpClient client = null;
    Stream s = null;
    try
    {
        listener = new TcpListener(60000);
        client = listener.AcceptTcpClient();
        Stream s = client.GetStrea();
        while(!Shutdown)  // use shutdown to gracefully shutdown thread.
        {
            try
            {
                string msg = s.ReadLine();  // This blocks the thread so setting shutdown = true will never occur unless a client sends a message.
                DoSomething(msg);
            }
            catch(IOException ex){ } // I would like to avoid using Exceptions for flow control
            catch(Exception ex) { throw; }
        }
    }
    catch(Exception ex)
    {
        LogException(ex);
        throw ex;
    }
    finally
    {
        if(listener != null) listener.Close();
        if(s != null) s.Close();
        if(client != null) client.Close();
    }
}

5voto

zmbq Points 18714

Définissez un délai d'attente sur le NetworkStream (client.ReadTimeout=...). Une fois l'opération de lecture terminée, vérifiez si le thread principal vous a signalé de vous arrêter (en définissant une variable ou un AutoResetEvent). Si l'arrêt a été signalé, quittez le processus de manière élégante. Sinon, essayez de lire à nouveau jusqu'au prochain délai d'attente.

La définition d'un délai d'attente de 0,5 ou 1 seconde devrait suffire. Vous serez en mesure de quitter le thread en temps voulu, tout en ménageant l'unité centrale.

2voto

GETah Points 10887

Existe-t-il un bon modèle permettant d'arrêter le fil en toute sécurité ?

Remplacez la boucle while par la suivante :

while (!interrupted){
   // Do something
}
// declare interrupted as volatile boolean
volatile bool interrupted;

Vérifiez ceci Exemple MSDN pour les détails. En mettant le booléen interrompu à true, le thread sortira de la boucle lorsqu'il vérifiera la condition while.

Existe-t-il un bon modèle pour permettre un arrêt sûr du TcpListener et du Client ?

Pour éviter les doublons, veuillez vérifier ceci Question

Pour ce qui est de votre question sur la manière de mettre fin à un thread bloquant sur ReadLine(); les éléments suivants listener.Server.Close(); devrait faire le travail et revenir de l'appel bloquant.

1voto

IDWMaster Points 2075

Peut-être qu'au lieu d'appeler Read sur un objet NetworkStream de manière synchrone, vous devriez utiliser BeginRead et EndRead pour le faire de manière asynchrone, et appeler Close() sur le NetworkStream lorsque vous en avez fini avec lui.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X