2011-02-12 188 views
1

我有一個線程在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;  
    } 
} 

回答

1

沒有安全的方法來殺死一個線程而不做一點工作:你不應該在一個線程上調用Abort;你需要做的是在線程中檢測到它在完成正常執行之前需要終止,然後你需要告訴它如何執行這個終止。

在C#中,最簡單的方法是使用BackgroundWorker,它本質上是一個在後臺線程中執行代碼的對象;它類似於調用invoke,除非你有更多的控制線程的執行。通過調用RunWorkerAsync()來啓動worker,並通過調用RunWorkerAsync()來指示它取消。調用RunWorkerAsync()後,後臺工作者的CancellationPending屬性設置爲true;你看在你的代碼的變化(即在while循環),當它是真實的你終止(即退出while循環)

while (!CancellationPending) 
{ 
    // do stuff 
} 

我個人都通過BackgroundWorkers線程,因爲它們易於理解和提供簡單的方法在後臺和主線程之間進行通信

-1

您應該在您的Reader功能中加入ManualResetEvent。而不是while(true),while(!mManualReset.WaitOne(0))。然後,在退出程序之前,先執行mManualReset.Set(),這將讓線程優雅地退出。

+0

如何使用該自動復位? – 2011-02-12 15:17:23

+0

真的很糟糕的方式來與線程交互太... – 2011-02-12 17:22:58