Describe a scenario where using `CancellationTokenSource.CancelAfter` might be problematic and how you would address it.

.NET interview question for Advanced practice.

Answer

Using CancellationTokenSource.CancelAfter can be problematic in operations that are not granular enough to check for cancellation frequently. If an operation performs a single, long-running, non-cancellable synchronous action, CancelAfter will signal cancellation, but the task will not stop until the synchronous action is complete, defeating the purpose of the timeout. For example, a task that calls a blocking I/O method or a CPU-intensive calculation without intermediate checks: csharp var cts = new CancellationTokenSource(); cts.CancelAfter(TimeSpan.FromSeconds(2)); try { await Task.Run(() = { // This synchronous, blocking operation takes 10 seconds // and does not check the token. SomeLegacyBlockingApiCall(10000); cts.Token.ThrowIfCancellationRequested(); // This check is too late. }, cts.Token); } catch(OperationCanceledException) { // This will only be caught after 10 seconds. } To address this, the long-running operation must be refactored to be truly asynchronous or to be broken into smaller chunks. Each chunk should be followed by a check for cancellation (token.ThrowIfCancellationRequested()). If refactoring the legacy call is impossible, the operation should be run in a separate process that can be killed, though this is a last resort due to its risks.

Explanation

The CancellationToken isn't just a simple flag; it can also carry a CancellationTokenRegistration which enables executing custom cancellation logic.

Related Questions