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 .