タイムアウト、IProgress<T>、非同期破棄(エミュレーション)
CancelAfterまたはTask.WhenAnyに基づくタイムアウトを適用し、UIに適した更新のためにIProgress を接続し、C# 6でtry/finallyを使って非同期クリーンアップを再現します。
「タイムアウト、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に記述します。
タイムアウトパターン
まとめ
まとめ: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フィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- CancellationTokenパターンと協調的キャンセル
- タイムアウト、IProgress 、非同期破棄(エミュレーション)
- レジリエンスの基礎:リトライとバックオフ