Home > Blockchain >  Task.Delay() cancellation not working on net7.0?
Task.Delay() cancellation not working on net7.0?

Time:10-15

Would anyone know why await Task.Delay(longTimeOut, cancellationToken); does not end up with TaskCanceledException (when the token is signalled) and continue waiting when targeting net7.0?

On net6.0 it throws as expected.

EDIT:

As stated below, the original question is misleading... Anyway between the net6/net7 there is a difference in the process termination caused by Console.CancelKeyPress, where on net6 there is some room for the task to report it's cancellation and throwing the exception, on net7 the process seems to be killed faster and thus the code handling cancellation is not even executed.

CodePudding user response:

Seems fine here; output:

TaskCanceledException
Took: 00:00:03.0577829

dotnet --info:

.NET SDK:
 Version:   7.0.100-rc.2.22477.23
 Commit:    0a5360315a

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.22000
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\7.0.100-rc.2.22477.23\

Host:
  Version:      7.0.0-rc.2.22472.3
  Architecture: x64
  Commit:       550605cc93

test:

var cancel = new CancellationTokenSource();
cancel.CancelAfter(TimeSpan.FromSeconds(3));
var watch = Stopwatch.StartNew();
try
{
    // works identically if a large integer is passed
    await Task.Delay(TimeSpan.FromHours(1), cancel.Token);
    Console.WriteLine("no fault");
}
catch (Exception ex)
{
    Console.WriteLine(ex.GetType().Name);
}
watch.Stop();
Console.WriteLine($"Took: {watch.Elapsed}");

If you're seeing something different: please post an entire runnable example.

CodePudding user response:

TLDR: The question is a bit misleading...

The main problem was the point where the cancellationToken got fired: Console.CancelKeyPress. Not sure why it works differently between net6/net7 (which I incorrectly stated as the cause), but there is the e.Cancel, which is counterintuitive (at leas for me) and I left the default value of false, and probably the whole process went the wrong way.

When I added automatic cancellation, it works as expected (so it's clear it's not the Task.Delay()'s issue).

    private static async Task Main(string[] args)
    {

        using var cts = new CancellationTokenSource(10_000); // cancelling automatically

        Console.CancelKeyPress  = (s, e) =>
        {
            Console.WriteLine("Cancelling manually...");
            cts.Cancel();
            e.Cancel = true; // This is the issue, as default is false, meaning: "Terminate the process after return."
        };

        try
        {
            Console.WriteLine("Starting...");
            await Task.Delay(20_000, cts.Token);
            Console.WriteLine("Done.");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Cancelled: {ex}.");
        }
    }

Meaning: on net6 the task is cancelled even when the process is terminating. On net7 it's not. At least in the debugger in Visual Studio (haven't tried plain executable).

  • Related