skip to Main Content

I´m still learning to code, and I’m making a new project with MDI forms (C# and Visual Studio 2019). In mdichild, I launched a task, but if the form is unloaded, the task still remains. I would like to know how cancel the task, even on a cancel button click.

The code:

private async void BuscaActualizaciones()
{
    await Task.Run(() => DoLongThing());
}

private void DoLongThing()
{
    //some hard stuff
}

private void BtnBuscar_Click(object sender, EventArgs e)
{
    //In here i launch the task with hard stuff
    BuscaActualizaciones();
}

This code works perfectly, but I need to cancel in some events, and I don’t know how.

I tried some home-made tricks, and read on Google about task cancellation, but all of them used Task in other way that I don’t understand. I’m still learning, and it is my first time with tasks.

3

Answers


  1. Chosen as BEST ANSWER
    CancellationTokenSource cts = new CancellationTokenSource ();
    
    private async void BuscaActualizaciones()
    {
        await Task.Run(() => DoLongThing(), cts.Token); 
    }
    
    private Void DoLongThing() 
    {
        //some hard stuff
    
           if (cts.IsCancellationRequested)
                  {
                     throw new TaskCanceledException();
                  }
    }
    
    private void CancelButton_Click(object sender, EventArgs e)
    {
        cts.Cancel();  // <-- here is the cancellation
    }
    

    It´s working perfectly. thank you to all with help. The cts.IsCancellationRequested I read in google. Thank you .


  2. As @freakish pointed out in the comment, the proper way to do this is using a CancellationToken. Here is a simple example, assuming you have button which cancels the task when clicked:

    CancellationTokenSource cts = new();
    
    private async Task BuscaActualizaciones()
    {
        await Task.Run(DoLongThing, cts.Token); 
    }
    
    private Task DoLongThing() // <-- needs to return a Task
    {
        //some hard stuff
        cts.Token.ThrowIfCancellationRequested();
        //some hard stuff
    }
    
    private void CancelButton_Click(object sender, EventArgs e)
    {
        cts.Cancel();  // <-- here is the cancallation
    }
    

    I also strongly recommend recommend the documentation regarding "Asynchronous programming with async and await".

    Login or Signup to reply.
  3. As others have pointed out, the correct solution will use a CancellationToken. However, you don’t want to pass it to Task.Run; you want to pass it to DoLongThing, as such:

    CancellationTokenSource cts = new ();
    
    private async void BuscaActualizaciones()
    {
      await Task.Run(() => DoLongThing(cts.Token)); 
    }
    
    private void DoLongThing(CancellationToken token)
    {
      ...
      token.ThrowIfCancellationRequested();
    }
    
    private void CancelButton_Click(object sender, EventArgs e)
    {
      cts.Cancel();
    }
    

    Polling for cancellation (ThrowIfCancellationRequested) is common for CPU-bound methods that need to periodically check if they’re canceled. I have a blog post that goes into more details on the subject.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search