Home > database >  Cancel task in c#
Cancel task in c#

Time:12-03

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.

CodePudding user response:

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".

CodePudding user response:

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.

CodePudding user response:

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 .

  • Related