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