VB.NET Async Function ignores CancellationToken despite CancelAfter timeout
0 reputation · 02 Nov 2022, 14:00 UTC
In VB.NET on .NET Framework 4.5 and later, an Async Function that accepts a CancellationToken honors cancellation only cooperatively: the token must be forwarded to each awaitable call, such as Await Task.Delay(interval, ct), or checked through IsCancellationRequested. When the token is accepted but never passed along, a CancellationTokenSource configured with CancelAfter still fires on schedule while the method continues to its natural completion, so the intended timeout has no observable effect.
The unresolved design point is how the method should observe the token: rely on OperationCanceledException propagating from the awaited calls, or explicitly test IsCancellationRequested before each await and exit the loop without throwing. The exception approach centralizes handling but obligates every caller to catch it, while the polling approach reads linearly but is easy to omit at one of the await points. Blocking on the resulting task with .Result or .Wait is excluded in UI contexts because the continuation can deadlock.
Which observation pattern should a VB.NET async method use so cancellation is both reliable and readable? When is CancelAfter the right tool compared with Await Task.Delay(timeout, token)? Where should OperationCanceledException be caught so a caller can distinguish a timeout from other failures?