0Pricing
C# Academy · Урок

Тайм-ауты, IProgress<T> и асинхронные освобождаемые ресурсы (эмуляция)

Применяйте тайм-ауты на основе CancelAfter или Task.WhenAny, подключайте IProgress для удобных обновлений интерфейса и эмулируйте асинхронное освобождение ресурсов через try/finally в C# 6.

«Тайм-ауты, IProgress<T> и асинхронные освобождаемые ресурсы (эмуляция)» — бесплатный урок C# Academy на CoddyKit. Это урок 2 из 3. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 3 уроков всего.

План

Цель:

  • Устанавливать тайм-аут с помощью CancelAfter
  • Устанавливать тайм-аут через Task.WhenAny
  • Отслеживать прогресс с помощью IProgress<T>
  • Использовать асинхронный шаблон очистки в C# 6 (try/finally)

Тайм-аут через CancelAfter

Используйте CancelAfter и передайте токен в асинхронный API; при тайм-ауте вызываемый метод кооперативно прекращает работу.

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");
    }
  }
}

Тайм-аут через WhenAny

Task.WhenAny сопоставляет выполнение операции с Task.Delay; если задержка завершается первой, выбрасывайте 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>

IProgress<T> отделяет работу от пользовательского интерфейса; производители вызывают Report, а потребители безопасно обновляют пользовательский интерфейс или поток.

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();
  }
}

Шаблон асинхронной очистки

В C# 6 отсутствует IAsyncDisposable; используйте try/finally и освобождайте ресурсы в finally после завершения ожидаемой операции.

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");
  }
}

Рекомендации

Советы:

  • Для простых тайм-аутов операций предпочитайте CancelAfter.
  • Используйте WhenAny для пользовательских сценариев тайм-аутов.
  • Делайте типы прогресса небольшими (например, целое число процентов или простая структура).
  • Всегда завершайте ожидание операций до освобождения ресурсов; помещайте освобождение в finally.

Шаблон тайм-аута

Быстрая проверка: как просто добавить тайм-аут к асинхронной операции в C# 6, не блокируя поток?

Итоги

Итоги: реализуйте тайм-ауты с помощью CancelAfter или WhenAny, сообщайте о прогрессе через IProgress<T> и имитируйте асинхронное освобождение ресурсов с помощью try/finally в C# 6.

Часто задаваемые вопросы

Урок «Тайм-ауты, IProgress<T> и асинхронные освобождаемые ресурсы (эмуляция)» бесплатный?

Да — полный текст урока «Тайм-ауты, IProgress<T> и асинхронные освобождаемые ресурсы (эмуляция)» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 3 уроков всего.

Чему я научусь в уроке «Тайм-ауты, IProgress<T> и асинхронные освобождаемые ресурсы (эмуляция)»?

Применяйте тайм-ауты на основе CancelAfter или Task.WhenAny, подключайте IProgress для удобных обновлений интерфейса и эмулируйте асинхронное освобождение ресурсов через try/finally в C# 6. Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C# Academy?

Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 3.

Сколько времени занимает урок «Тайм-ауты, IProgress<T> и асинхронные освобождаемые ресурсы (эмуляция)»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C# Academy?

Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Шаблоны CancellationToken и кооперативная отмена
  2. Тайм-ауты, IProgress и асинхронные освобождаемые ресурсы (эмуляция)
  3. Основы устойчивости: повторные попытки и интервалы между ними
← Назад к C# Academy