Quick answer: Godot 4 C# CancellationToken.Cancel() blocking the main thread when called from a signal handler? Cancel runs callbacks synchronously; long callbacks freeze the engine - use CancellationTokenSource.CancelAsync.
Network task cancel takes 800ms because the registered callback runs inline.
Use CancelAsync
await cts.CancelAsync();Available .NET 8+. Callbacks run on a thread pool task; main thread returns immediately.
Or detach the callback
Register cancellation handlers on a Task.Run wrapper. The detach moves the work off the main thread.
Audit registered callbacks
Cancel callbacks should be short. Anything > 1ms belongs on a worker.
“Cancellation callbacks run somewhere. Default is somewhere is the caller's thread.”
Build a cancellation helper that wraps token sources with async cancel + worker dispatch. Misuse-resistant.