0Pricing
C# Academy · Lekcja

Limity czasu, IProgress<T> i zasoby async (emulacja)

Proszę stosować limity czasu za pomocą CancelAfter lub Task.WhenAny, podłączać IProgress do aktualizacji przyjaznych interfejsowi użytkownika oraz używać try/finally do emulowania asynchronicznego sprzątania w C# 6.

Limity czasu, IProgress<T> i zasoby async (emulacja) to bezpłatna lekcja C# Academy na CoddyKit. To lekcja 2 z 3. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C# Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C# Academy zawiera 3 lekcji w sumie.

Plan

Cel:

  • Limit czasu za pomocą CancelAfter
  • Limit czasu za pomocą Task.WhenAny
  • Raportowanie postępu za pomocą IProgress<T>
  • Wzorzec asynchronicznego czyszczenia w C# 6 (try/finally)

Limit czasu za pomocą CancelAfter

Należy użyć CancelAfter i przekazać token do asynchronicznego interfejsu API; metoda wywoływana zatrzyma się w sposób współdziałający po przekroczeniu limitu czasu.

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

Limit czasu za pomocą WhenAny

Task.WhenAny uruchamia wyścig między pracą a Task.Delay; jeśli wygra opóźnienie, należy zgłosić wyjątek 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);
    }
  }
}

Przykład IProgress<T>

IProgress<T> oddziela pracę od interfejsu użytkownika; producenci wywołują Report, a konsumenci bezpiecznie aktualizują interfejs użytkownika lub wątek.

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

Wzorzec asynchronicznego czyszczenia

W C# 6 brakuje interfejsu IAsyncDisposable; należy używać konstrukcji try/finally i zwalniać zasoby w sekcji finally po zakończeniu oczekiwanej pracy.

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

Najlepsze praktyki

Wskazówki:

  • W przypadku prostych limitów czasu operacji należy preferować CancelAfter.
  • Do niestandardowych przepływów z limitem czasu należy używać WhenAny.
  • Typy opisujące postęp powinny być niewielkie (np. liczba całkowita oznaczająca procent lub prosta struktura).
  • Zawsze należy zakończyć oczekiwanie na operacje przed zwolnieniem zasobów; zwalnianie zasobów należy umieszczać w sekcji finally.

Wzorzec limitu czasu

Szybkie sprawdzenie: Jaki jest prosty sposób dodania limitu czasu do operacji asynchronicznej w C# 6 bez blokowania?

Podsumowanie

Podsumowanie: Limity czasu należy implementować za pomocą CancelAfter lub WhenAny, postęp raportować za pomocą IProgress<T>, a asynchroniczne zwalnianie zasobów emulować w C# 6 za pomocą konstrukcji try/finally.

Często zadawane pytania

Czy lekcja „Limity czasu, IProgress<T> i zasoby async (emulacja)” jest bezpłatna?

Tak — pełny tekst „Limity czasu, IProgress<T> i zasoby async (emulacja)” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C# Academy, przejdź na CoddyKit PRO. Kurs C# Academy zawiera 3 lekcji w sumie.

Co nauczysz się w „Limity czasu, IProgress<T> i zasoby async (emulacja)”?

Proszę stosować limity czasu za pomocą CancelAfter lub Task.WhenAny, podłączać IProgress do aktualizacji przyjaznych interfejsowi użytkownika oraz używać try/finally do emulowania asynchronicznego sp… Ćwiczysz C# Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć C# Academy?

Nie wymagamy żadnego doświadczenia. C# Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 3.

Ile czasu zajmuje lekcja „Limity czasu, IProgress<T> i zasoby async (emulacja)”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji C# Academy?

Tak. Każda lekcja C# Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Wzorce CancellationToken i kooperacyjne anulowanie
  2. Limity czasu, IProgress i zasoby async (emulacja)
  3. Podstawy odporności: ponawianie i backoff
← Powrót do C# Academy