Skip to content
Search lessons, topics, tests…
Esc

    ↑ ↓ moveEnter openEsc close

    Guided course · .NET Runtime and Concurrency

    C# Async Reliability Interview Path: back to the course

    Module 1 · Control Flow, Cancellation, and Time Budgets · Lesson 2 of 4

    Timeout Budgets with WaitAsync and Linked Tokens

    A timeout is a caller policy: “I will wait no longer than this.” Cancellation is an operation protocol: “Please stop if you can.” Robust code often needs both.

    Bound the underlying operation

    C#
    public async Task<Quote> GetQuoteAsync(
        string sku,
        TimeProvider timeProvider,
        CancellationToken requestAborted)
    {
        using var timeout = new CancellationTokenSource(
            TimeSpan.FromSeconds(2),
            timeProvider);
        using var budget = CancellationTokenSource.CreateLinkedTokenSource(
            requestAborted,
            timeout.Token);
    
        return await pricingClient.GetQuoteAsync(sku, budget.Token);
    }

    The linked source combines caller cancellation with the service's own two-second budget. The dependency must observe budget.Token for the request to stop promptly.

    Bound only the wait

    C#
    var result = await backgroundTask.WaitAsync(
        TimeSpan.FromSeconds(2),
        requestAborted);

    If the interval expires, WaitAsync throws TimeoutException; if the token is canceled, it throws cancellation. The original backgroundTask may still be running. This is correct when the work is intentionally shared or cached, but wasteful when it represents a per-request HTTP or database call.

    Use one end-to-end budget

    Stacking a five-second controller timeout, five-second service timeout, and five-second database timeout can produce a fifteen-second user experience. Start with an end-to-end deadline and allocate smaller dependency budgets within it.

    Reserve time for retries and response serialization. A retry policy must stop when the remaining budget cannot accommodate another attempt.

    Testing with TimeProvider

    Inject TimeProvider into code that owns timers or CancelAfter. A fake provider lets tests advance virtual time instead of waiting for seconds on the wall clock.

    Tests should separately prove caller cancellation, service-budget expiry, successful early completion, wait-only timeout behavior, and resource cleanup.

    Operational signals

    Report caller cancellation and service timeout separately. They have different owners and remedies. Track dependency name, configured budget, elapsed time, retry count, and whether the underlying call acknowledged cancellation.

    The interview-quality answer is concise: WaitAsync limits waiting, a token requests cooperative stopping, and a linked source composes cancellation ownership. Then explain why the underlying operation must receive the token.

    Sign in to mark lessons done and keep your place in the course.Sign in