Как убить нить? - PullRequest
       23

Как убить нить?

1 голос
/ 12 февраля 2011

У меня есть нить в Winform. После того как я выйду из приложения или закрою консольное приложение сервера, поток продолжает работать. Вот код:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    StreamReader sr;
    StreamWriter sw;
    TcpClient connection;
    string name;

    private void Form1_Load(object sender, EventArgs e)
    {
        connection = new TcpClient("127.0.0.1", 5000);
        sr = new StreamReader(connection.GetStream());
        sw = new StreamWriter(connection.GetStream());
        ChatterScreen.Text = "Welcome, please enter your name";
    }

    private void button3_Click(object sender, EventArgs e)
    {
        //Thread t2 = new Thread(Reader);
        //t2.IsBackground = true;
        //t2.Start(connection);
        ThreadPool.QueueUserWorkItem(Reader,connection);//How do i kill this thread
        name = InputLine.Text;
    }

    string textinput;
    private void button2_Click(object sender, EventArgs e)
    {
        textinput = InputLine.Text;
        sw.WriteLine(name+":"+textinput);
        sw.Flush();
    }

    string msg;
    string allMessages;
    public void Reader(object o)
    {
        TcpClient con = o as TcpClient;
        if (con == null)
            return;
        while (true)
        {
            msg = sr.ReadLine() + Environment.NewLine;
            allMessages += msg;
            Invoke(new Action(Output)); // An exception is thrown here constantly. sometimes it is thrown and sometimes if i quite the server application , the winform application freezes.
            Invoke(new Action(AddNameList));
        }
    }

    public void Output()
    {
        ChatterScreen.Text = allMessages;     
    }
}

Ответы [ 2 ]

1 голос
/ 12 февраля 2011

Не существует безопасного способа убить поток, не выполнив немного работы: вы никогда не должны вызывать Abort для потока; что вам нужно сделать, это обнаружить в потоке, что требуется завершить работу до завершения его нормального выполнения, а затем вам нужно сообщить ему, как выполнить это завершение.

В C # самый простой способ сделать это - использовать BackgroundWorker , который по сути является объектом, выполняющим код в фоновом потоке; это похоже на вызов invoke, за исключением того, что вы имеете больший контроль над выполнением потока. Вы запускаете работника, вызывая RunWorkerAsync (), и вы приказываете его отменить, вызывая RunWorkerAsync (). После вызова RunWorkerAsync () для свойства CancellationPending фонового работника устанавливается значение true; вы наблюдаете за этим изменением в своем коде (т. е. в цикле while), а когда оно истинно, вы завершаете (т. е. выходите из цикла while)

while (!CancellationPending )
{
  // do stuff
}

Лично я делаю все потоки через BackgroundWorkers, потому что они просты для понимания и предлагают простые способы связи между фоном и основными потоками

0 голосов
/ 12 февраля 2011

Вы должны добавить ManualResetEvent в функцию Reader.Вместо while (true) сделайте while (! MManualReset.WaitOne (0)).Затем, прежде чем выйти из программы, выполните mManualReset.Set (). Это позволит изящно завершить поток.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...