I want to know how to cancel Tasks. already read some articles like this: https://docs.microsoft.com/en-us/dotnet/standard/threading/cancellation-in-managed-threads?redirectedfrom=MSDN
But i have already done Tasks and want to know how can i make them cancelable.
Either all at once and if that is not possible then one task should be canceled and then he should cancel the next one until all are gone.
EDIT Is that the correct using of CancellationToken? Tasks continue to run as I wanted, but when I press the cancel button I get an error. If I start my published version, the application just closes:* enter image description here
void btnPause_Click(object sender, EventArgs e)
{
cts.Cancel();
}
async void btnStart_Click(object sender, EventArgs e)
{
try
{
cts = new CancellationTokenSource();
var token = cts.Token;
var t1 = Task.Run(() => START(token));
await Task.WhenAny(new[] { t1 });
}
catch (OperationCanceledException)
{
// Handle canceled
}
catch (Exception)
{
// Handle other exceptions
}
}
///////////////////////////////////////////
async void START(CancellationToken token)
{
for (int i = 0; i < 1; i )
{
token.ThrowIfCancellationRequested();
await Task.Delay(100, token);
try {
if()
{
}
}catch { }
}
Thread.Sleep(2000);
var t2 = Task.Run(() => START2(token));
await Task.WhenAny(new[] { t2});
}
///////////////////////////////////////////////
async void START2(CancellationToken token)
{
for (int i = 0; i < 10; i )
{
token.ThrowIfCancellationRequested();
await Task.Delay(100, token);
try {
if()
{
}
}catch { }
}
Thread.Sleep(7000);
var t3 = Task.Run(() => MOVE(token));
await Task.WhenAny(new[] {t3});
}
//////////////////////////////////////////
async void MOVE(CancellationToken token)
{
for (int i = 0; i < 3; i )
{
token.ThrowIfCancellationRequested();
await Task.Delay(100, token);
try {
if()
{
}
}catch { }
}
var t4 = Task.Run(() => MOVE2(token));
await Task.WhenAny(new[] {t4 });
}
CodePudding user response:
Use a CancellationTokenSource, in a somewhat simplified example:
CancellationTokenSource cts = new CancellationTokenSource();
async void Cancel_Click(object sender, EventArgs e)
{
cts.Cancel();
}
async void btnStart_Click(object sender, EventArgs e)
{
try{
cts = new CancellationTokenSource();
var token = cts.Token;
var t1 = Task.Run(() => Start(token));
var t2 = Task.Run(() => Start(token));
await Task.WhenAny(new []{t1, t2});
}
catch(OperationCancelledException){
// Handle canceled
}
catch(Exception){
// Handle other exceptions
}
}
void Start(CancellationToken token)
{
for (int i = 0; i < 100; i )
{
token.ThrowIfCancellationRequested();
// Do work
Thread.Sleep(100);
}
}
When the button is clicked it will first create a new cancellationTokenSource, then start two tasks on background threads, both using the token from the newly created token source. When the cancelButton is pressed the token will be set into canceled-state, and the next time each background thread calls ThrowIfCancellationRequested they will throw an exception. This will put the task into a canceled-state, and awaiting this will throw an operationCancelledException that need to be caught. Note that when awaiting multiple tasks you might get an aggregateException that wraps multiple exceptions and need to be unpacked.