Rushali Watane
Rushali Watane

Reputation: 51

Stop Thread on Button Click in C#

I want to stop my thread on button click event and As I am new to threads I don't know how can I do this in C#. My application is of TCP Client and I am reading TCP server continuously using this thread

public void ClientReceive()
{
    try
    {

        stream = client.GetStream(); //Gets The Stream of The Connection
        new Thread(() => // Thread (like Timer)
        //Thread mythread = new Thread(ClientReceive);
        {
            //MessageBox.Show(stream.Read(datalength, 0, 256).ToString());
            //(i = stream.Read(datalength, 0, 256)) != 0
            while (i != 1)//Keeps Trying to Receive the Size of the Message or Data
            {
                // how to make a byte E.X byte[] examlpe = new byte[the size of the byte here] , i used BitConverter.ToInt32(datalength,0) cuz i received the length of the data in byte called datalength :D
                // byte[] data = BitConverter.GetBytes(1000); // Creates a Byte for the data to be Received On
                byte[] data = new byte[1000];
                stream.Read(data, 0, data.Length); //Receives The Real Data not the Size
                this.Invoke((MethodInvoker)delegate // To Write the Received data
                {
                    //txtLog.Text += System.Environment.NewLine + "Server : " + Encoding.Default.GetString(data); // Encoding.Default.GetString(data); Converts Bytes Received to String
                    DateTime now = DateTime.Now;
                    //MessageBox.Show(Encoding.Default.GetString(data));
                    if (Encoding.Default.GetString(data) != "")
                    {
                        txtLog.Text += System.Environment.NewLine + now.ToString() + " Received : \r\n" + Encoding.Default.GetString(data) + "\r\n";

                    }
                    for (int j = 0; j < txtLog.Lines.Length; j++)
                    {
                        if (txtLog.Lines[j].Contains("Received"))
                        {
                            this.CheckKeyword(txtLog.Lines[j + 1], Color.Red, 0);
                        }
                        if (txtLog.Lines[j].Contains("Sent"))
                        {
                            this.CheckKeyword(txtLog.Lines[j + 1], Color.Blue, 0);
                        }
                    }

                });
            }
       // mythread.Start();
        }).Start(); // Start the Thread
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());  
    }
}

Upvotes: 3

Views: 6844

Answers (2)

Shaharyar
Shaharyar

Reputation: 12459

I recommend you to use Task instead of Thread. Because Aborting a thread is not recommnded and it may affect your data as well.

Eric Lippert explained it very well here.

Here is the code for you:

private CancellationTokenSource tokenSource; //global field

public void ClientReceive()
{
    try
    {
        //initiate CancellationTokenSource
        tokenSource = new CancellationTokenSource();

        stream = client.GetStream(); //Gets The Stream of The Connection

        //start parallel task
        Task.Factory.StartNew(() =>
        {           
            //MessageBox.Show(stream.Read(datalength, 0, 256).ToString());
            //(i = stream.Read(datalength, 0, 256)) != 0
            while (i != 1)//Keeps Trying to Receive the Size of the Message or Data
            {
                // how to make a byte E.X byte[] examlpe = new byte[the size of the byte here] , i used BitConverter.ToInt32(datalength,0) cuz i received the length of the data in byte called datalength :D
                // byte[] data = BitConverter.GetBytes(1000); // Creates a Byte for the data to be Received On
                byte[] data = new byte[1000];
                stream.Read(data, 0, data.Length); //Receives The Real Data not the Size
                this.Invoke((MethodInvoker)delegate // To Write the Received data
                {
                    //txtLog.Text += System.Environment.NewLine + "Server : " + Encoding.Default.GetString(data); // Encoding.Default.GetString(data); Converts Bytes Received to String
                    DateTime now = DateTime.Now;
                    //MessageBox.Show(Encoding.Default.GetString(data));
                    if (Encoding.Default.GetString(data) != "")
                    {
                        txtLog.Text += System.Environment.NewLine + now.ToString() + " Received : \r\n" + Encoding.Default.GetString(data) + "\r\n";

                    }
                    for (int j = 0; j < txtLog.Lines.Length; j++)
                    {
                        if (txtLog.Lines[j].Contains("Received"))
                        {
                            this.CheckKeyword(txtLog.Lines[j + 1], Color.Red, 0);
                        }
                        if (txtLog.Lines[j].Contains("Sent"))
                        {
                            this.CheckKeyword(txtLog.Lines[j + 1], Color.Blue, 0);
                        }
                    }

                });
            }
        }, tokenSource.Token);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());  
    }
}

//call this method on cancel button
private void cancelTask()
{
    if(tokenSource != null) //check if its even initialized or not
        tokenSource.Cancel();
}

If you need more explanation about TPL refer to this article.

Upvotes: 3

Jamaxack
Jamaxack

Reputation: 2460

Try this:

   Thread thread = new Thread(() =>
   {
       Console.WriteLine("Some actions inside thread");
   });  
   thread.Start();
   thread.Abort();

First you need to set your thread to some field and then you can control it as shown in code, Start(),Abort().

If you want Abort() thread from button click event you need to move thread field out of method, that way you can get access from your button click event.

Hope Helps!

Upvotes: 2

Related Questions