Home > Blockchain >  C# form, how to stop a thread with a button?
C# form, how to stop a thread with a button?

Time:01-27

I am doing a form application in C#, it's a client that receives string with socket from server, I have a thread which runs an endless loop with inside the receive function. When I click a button I have to stop this thread, I have tried with a boolean variable but it doesn't work because the function get stuck on the receive function and the control on the boolean variable is done before when is still true. How Can I do to stop this thread?

This is the function which is runned by the thread:

 public void Prova()
        {                    
                while (true)
                {
                    string str = frmRegister.c.Receive();
                    ... doing things...
                }
        }

The thread is started in this way:

public Form1()
        {
            InitializeComponent();
            t1 = new Thread(Prova);
            t1.Start();       
        }

And I have to stop the thread here:

    private void goBack_Click(object sender, EventArgs e)
        {         
            new Form2().Show();           
            this.Hide();
        }

The following is my attempt with the CancellationToken:

private CancellationTokenSource tokenSource;

public void Prova(CancellationToken token)
       {         
           while(!token.IsCancellationRequested){           
               while (true)
               {
                   string str = frmRegister.c.Receive();
                   ... doing things...
               }
            }
       }

public Form1()
       {
         InitializeComponent();
         tokenSource = new CancellationTokenSource();
         var task = Task.Run(() => Prova(tokenSource.Token));       
       }

private void goBack_Click(object sender, EventArgs e)
       {      
           tokenSource.Cancel();
           new Form2().Show();           
           this.Hide();
       }

CodePudding user response:

Given your sample this should work:

private CancellationTokenSource tokenSource;

public void Prova(CancellationToken token = default)
       {         
           while(!token.IsCancellationRequested) {
                   string str = frmRegister.c.Receive();
                   ... doing things...
               }
            }
       }

Or even:

public void Prova(CancellationToken token = default)
        {                    
                while (true)
                {
                    token.ThrowIfCancellationRequested();

                    string str = frmRegister.c.Receive();
                    ... doing things...
                }
        }

Or:

public void Prova(CancellationToken token = default)
        {                    
                while (true)
                {
                    if(token.IsCancellationRequested)
                       return;

                    string str = frmRegister.c.Receive();
                    ... doing things...
                }
        }

Basically get rid of the double while loop and it works.

CodePudding user response:

Why did you use Thread instead of Task?

In your case

Thread th;
CancellationTokenSource cts = new CancellationTokenSource();

public void Prova(CancellationToken cancellationToken)
{                    
        while (true)
        {
            cancellationToken.ThrowIfCancellationRequested();
            string str = frmRegister.c.Receive();
            ... doing things...
        }
}

public Form1()
{
        InitializeComponent();
        th = new Thread(() => { Prova(cts.Token);  });
        th.Start();;       
}

private void goBack_Click(object sender, EventArgs e)
{         
    cts.Cancel();
}

With task

    Task th;
    CancellationTokenSource cts = new CancellationTokenSource();

    public void Prova(CancellationToken cancellationToken)
    {
        while (true)
        {
            cancellationToken.ThrowIfCancellationRequested();
            ...process
        }
    }

    public Form1()
    {
        InitializeComponent();
        th = Task.Run(() => { Prova(cts.Token); }, cts.Token);
        th.Start(); ;
    }

    private void goBack_Click(object sender, EventArgs e)
    {
        cts.Cancel();
    }
  •  Tags:  
  • Related