Правильное завершение потока сервера - PullRequest
1 голос
/ 08 февраля 2012

У меня есть форма окна. В конструкторе серверный поток запускается

thServer = new Thread(ServerThread);
thServer.Start();

В потоке сервера есть цикл прослушивания TCP:

 while (true) {
    TcpClient client = server.AcceptTcpClient();
    ...
    }

Когда я закрываю основную форму, этот поток продолжает ожидать запросы TCPClient. Как я могу остановить эту рутину? Спасибо.

Ответы [ 5 ]

1 голос
/ 08 февраля 2012
public partial class Form1 : Form
{
    Thread theServer = null;

    public Form1()
    {
        InitializeComponent();

        this.FormClosed += new FormClosedEventHandler( Form1_FormClosed );

        theServer = new Thread( ServerThread );
        theServer.IsBackground = true;
        theServer.Start();

    }

    void ServerThread()
    {
        //TODO
    }

    private void Form1_FormClosed( object sender, FormClosedEventArgs e )
    {
        theServer.Interrupt();
        theServer.Join( TimeSpan.FromSeconds( 2 ) );
    }
}
1 голос
/ 08 февраля 2012

Самый простой способ - пометить поток как фоновый поток - тогда он не будет поддерживать ваш процесс при закрытии основной формы:

thServer = new Thread(ServerThread);
thServer.IsBackground = true;
thServer.Start();

MSDN: Thread.IsBackground

0 голосов
/ 08 февраля 2012

Сделайте специальную логическую переменную, указывающую, что форма собирается закрыться. Проверьте его значение в фоновом потоке и прервите цикл, если оно истинно. В основной форме установите значение переменной в true и вызовите thServer.Join (), чтобы дождаться окончания потока. Тогда вы можете безопасно закрыть форма. Примерно так:

В обработчике закрытия формы:

abortThread = true;
thServer.Join();

В цикле потока сервера:

while (true)
{
   if (abortThread)
      break;

   TcpClient client = server.AcceptTcpClient();
   ...
}
0 голосов
/ 08 февраля 2012

Вот решение этой же проблемы. (взгляните на класс SimpleServer)

Идея состоит в том, чтобы остановить TcpClient, поэтому вызов AcceptTcpClient прерывается. После вызова AcceptTcpClient вам, возможно, придется спросить, открыт ли еще сокет.

0 голосов
/ 08 февраля 2012

Одним из подходов было бы добавить флаг, который действует как условие цикла while. Конечно, вы также можете установить свойство IsBackground вашего объекта Thread, но вы можете захотеть выполнить некоторый код очистки.

Пример:

class Server : IDisposable
{
    private bool running = false;
    private Thread thServer;

    public Server()
    {
        thServer = new Thread(ServerThread);
        thServer.Start();
    }

    public void Dispose()
    {
        running = false;
        // other clean-up code
    }

    private ServerThread()
    {
        running = true;
        while (running)
        {
            // ...
        }
    }
}

Использование:

using (Server server = new Server())
{
    // ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...