C# Academy · レッスン

タイムアウト、IProgress<T>、非同期破棄(エミュレーション)

CancelAfterまたはTask.WhenAnyに基づくタイムアウトを適用し、UIに適した更新のためにIProgress を接続し、C# 6でtry/finallyを使って非同期クリーンアップを再現します。

レッスン 2/38 ステップ

「タイムアウト、IProgress<T>、非同期破棄(エミュレーション)」はCoddyKit上の無料C# Academyレッスンです。 これはレッスン2/3です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これは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>によって処理と UI を分離できます。生成側はReportを呼び出し、利用側は UI やスレッドを安全に更新します。

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を使用し、awaitした処理が完了した後に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を使用します。
  • 進行状況の型は小さく保ちます(例:パーセントを表す int や単純な構造体)。
  • リソースを破棄する前に、必ずすべての await を完了させます。破棄処理はfinallyに記述します。

タイムアウトパターン

簡単な確認です。C# 6でブロッキングせずに非同期処理へタイムアウトを追加する簡単な方法は何ですか?

まとめ

まとめ:CancelAfterまたはWhenAnyでタイムアウトを実装し、IProgress<T>で進行状況を報告し、C# 6ではtry/finallyで非同期破棄を再現します。

無料で開始

AI チューターと学ぶ C# — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
93
レッスン
346

よくある質問

「タイムアウト、IProgress<T>、非同期破棄(エミュレーション)」レッスンは無料ですか?

はい。「タイムアウト、IProgress<T>、非同期破棄(エミュレーション)」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C# Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C# Academyコースには全3レッスンが含まれています。

「タイムアウト、IProgress<T>、非同期破棄(エミュレーション)」で何を学びますか?

CancelAfterまたはTask.WhenAnyに基づくタイムアウトを適用し、UIに適した更新のためにIProgress を接続し、C# 6でtry/finallyを使って非同期クリーンアップを再現します。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C# Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC# Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/3です。

「タイムアウト、IProgress<T>、非同期破棄(エミュレーション)」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC# Academyレッスンでコードを書いて実行できますか?

はい。すべてのC# Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. CancellationTokenパターンと協調的キャンセル
  2. タイムアウト、IProgress 、非同期破棄(エミュレーション)
  3. レジリエンスの基礎:リトライとバックオフ
← C# Academyに戻る