0Pricing
C# Academy · Lesson

Timeouts, IProgress<T>, async disposables (emulation)

Apply CancelAfter or Task.WhenAny-based timeouts, wire IProgress for UI-friendly updates, and use try/finally to emulate async cleanup in C# 6.

Timeouts, IProgress<T>, async disposables (emulation) is a free C# Academy lesson on CoddyKit — lesson 2 of 3. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C# Academy learning path, one of 3 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Plan

Aim:

  • Timeout with CancelAfter
  • Timeout via Task.WhenAny
  • Progress with IProgress<T>
  • Async cleanup pattern in C# 6 (try/finally)

Timeout via CancelAfter

Use CancelAfter and pass the token to the async API; the callee stops cooperatively on timeout.

using System;
using System.Threading;
using System.Threading.Tasks;

public class Program
{
  static async Task<string> SlowOpAsync(CancellationToken ct)
  {
    // Simulate slow I/O that honors cancellation
    await Task.Delay(500, ct);
    return "OK";
  }

  public static void Main(string[] args)
  {
    var cts = new CancellationTokenSource();
    cts.CancelAfter(150); // timeout after 150 ms

    Task<string> t = SlowOpAsync(cts.Token);
    try
    {
      string result = t.GetAwaiter().GetResult(); // demo only
      Console.WriteLine(result);
    }
    catch (OperationCanceledException)
    {
      Console.WriteLine("Timed out");
    }
  }
}

Timeout via WhenAny

Task.WhenAny races the work against Task.Delay; if delay wins, throw a TimeoutException.

using System;
using System.Threading.Tasks;

public class Program
{
  // Wrap any Task<T> with a timeout using WhenAny
  static async Task<T> WithTimeoutAsync<T>(Task<T> work, int milliseconds)
  {
    Task delay = Task.Delay(milliseconds);
    Task first = await Task.WhenAny(work, delay);
    if (first == work) return await work; // completed in time
    throw new TimeoutException("Operation timed out");
  }

  static async Task<int> ComputeAsync()
  {
    await Task.Delay(300); // pretend work
    return 7;
  }

  public static void Main(string[] args)
  {
    try
    {
      int v = WithTimeoutAsync(ComputeAsync(), 100).GetAwaiter().GetResult();
      Console.WriteLine("Value " + v);
    }
    catch (TimeoutException ex)
    {
      Console.WriteLine(ex.Message);
    }
  }
}

IProgress<T> demo

IProgress<T> decouples work from UI; producers call Report, consumers update UI/thread safely.

using System;
using System.Threading.Tasks;

public class Program
{
  static async Task DownloadAsync(IProgress<int> progress)
  {
    // Report 0..100 in steps; UI would receive ProgressChanged on its context
    for (int p = 0; p <= 100; p += 25)
    {
      await Task.Delay(60);
      if (progress != null) progress.Report(p);
    }
  }

  public static void Main(string[] args)
  {
    Progress<int> prog = new Progress<int>(percent =>
    {
      Console.WriteLine("Progress: " + percent + "%");
    });

    DownloadAsync(prog).GetAwaiter().GetResult();
  }
}

Async cleanup pattern

C# 6 lacks IAsyncDisposable; use try/finally and dispose in finally after awaited work completes.

using System;
using System.IO;
using System.Threading.Tasks;

public class Program
{
  static async Task WriteThenCloseAsync(string path)
  {
    // C# 6 has no IAsyncDisposable; emulate with try/finally.
    FileStream fs = null;
    StreamWriter sw = null;
    try
    {
      fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None);
      sw = new StreamWriter(fs);
      await sw.WriteAsync("hello"); // do async work
      await sw.FlushAsync();        // ensure data is flushed
    }
    finally
    {
      // Dispose synchronously in finally
      if (sw != null) sw.Dispose();
      else if (fs != null) fs.Dispose();
    }
  }

  public static void Main(string[] args)
  {
    WriteThenCloseAsync("out.txt").GetAwaiter().GetResult();
    Console.WriteLine("Written");
  }
}

Best practices

Tips:

  • Prefer CancelAfter for simple operation timeouts.
  • Use WhenAny for custom timeout flows.
  • Keep progress types small (e.g., percent int or a simple struct).
  • Always finish awaits before disposing resources; put disposal in finally.

Timeout pattern

Quick check: What is a simple way to add a timeout to an async operation in C# 6 without blocking?

Recap

Recap: Implement timeouts with CancelAfter or WhenAny, report progress via IProgress<T>, and emulate async disposal with try/finally in C# 6.

Frequently asked questions

Is the “Timeouts, IProgress<T>, async disposables (emulation)” lesson free?

Yes — the full text of “Timeouts, IProgress<T>, async disposables (emulation)” is free to read here on the web, and the C# Academy course includes 3 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C# Academy course, upgrade to CoddyKit PRO.

What will I learn in “Timeouts, IProgress<T>, async disposables (emulation)”?

Apply CancelAfter or Task.WhenAny-based timeouts, wire IProgress for UI-friendly updates, and use try/finally to emulate async cleanup in C# 6. You practise C# Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start C# Academy?

No prior experience is required. C# Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 3, so you can start here or from the beginning and move at your own pace.

How long does the “Timeouts, IProgress<T>, async disposables (emulation)” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this C# Academy lesson?

Yes. Every C# Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. CancellationToken patterns; cooperative cancel
  2. Timeouts, IProgress , async disposables (emulation)
  3. Resilience basics: retry & backoff
← Back to C# Academy