@prefix schema: <https://schema.org/> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix ks: <https://comcomponent.com/vocab/> .

<https://comcomponent.com/blog/2026/03/09/001-csharp-async-await-best-practices/#article>
    schema:about <https://comcomponent.com/knowledge/io-bound-operation/>, <https://comcomponent.com/knowledge/cpu-bound-operation/> ;
    schema:mentions <https://comcomponent.com/knowledge/ui-thread-context/>, <https://comcomponent.com/knowledge/asp-net-core-request-thread/>, <https://comcomponent.com/knowledge/generic-library-code/>, <https://comcomponent.com/knowledge/event-handler-method/>, <https://comcomponent.com/knowledge/regular-async-method/>, <https://comcomponent.com/knowledge/task-whenall/>, <https://comcomponent.com/knowledge/task-whenany/>, <https://comcomponent.com/knowledge/parallel-foreachasync/>, <https://comcomponent.com/knowledge/semaphoreslim/>, <https://comcomponent.com/knowledge/channel-t/>, <https://comcomponent.com/knowledge/backpressure/>, <https://comcomponent.com/knowledge/backgroundservice/>, <https://comcomponent.com/knowledge/ihostedservice/>, <https://comcomponent.com/knowledge/fire-and-forget/>, <https://comcomponent.com/knowledge/decoupled-background-work/>, <https://comcomponent.com/knowledge/periodictimer/>, <https://comcomponent.com/knowledge/iasyncenumerable/>, <https://comcomponent.com/knowledge/await-using/>, <https://comcomponent.com/knowledge/valuetask/>, <https://comcomponent.com/knowledge/async-void/>, <https://comcomponent.com/knowledge/taskrun-dotnet/>, <https://comcomponent.com/knowledge/configureawait-false/>, <https://comcomponent.com/knowledge/synchronizationcontext/>, <https://comcomponent.com/knowledge/sync-over-async/>, <https://comcomponent.com/knowledge/cancellationtoken-dotnet/>, <https://comcomponent.com/knowledge/threadpool-starvation/> .

<https://comcomponent.com/knowledge/io-bound-operation/> a skos:Concept ;
    skos:prefLabel "I/O-bound処理"@ja ;
    skos:definition "HTTP、DB、ファイル、ソケットなど、外部の完了待ちが中心の処理。待っている間にスレッドを他の仕事へ返せる。"@ja ;
    skos:altLabel "I/O待ち"@ja .

<https://comcomponent.com/knowledge/cpu-bound-operation/> a skos:Concept ;
    skos:prefLabel "CPU-bound処理"@ja ;
    skos:definition "圧縮、画像処理、ハッシュ計算、重い変換など、CPU計算そのものが中心の処理。どのスレッドで動かすかや並列数の決め方が主題になる。"@ja ;
    skos:altLabel "CPU計算"@ja .

<https://comcomponent.com/knowledge/taskrun-dotnet/> a skos:Concept ;
    skos:prefLabel "Task.Run"@ja ;
    skos:definition "CPUを使う処理を.NETスレッドプールのワーカースレッドへ明示的にオフロードするためのAPI。I/OバウンドのTaskに使う必要はない。"@ja ;
    ks:notRecommendedFor <https://comcomponent.com/knowledge/io-bound-operation/> ;
    ks:recommendedFor <https://comcomponent.com/knowledge/cpu-bound-operation/> ;
    ks:recommendedFor <https://comcomponent.com/knowledge/ui-thread-context/> ;
    ks:notRecommendedFor <https://comcomponent.com/knowledge/asp-net-core-request-thread/> .

<https://comcomponent.com/knowledge/ui-thread-context/> a skos:Concept ;
    skos:prefLabel "UIスレッドのコンテキスト"@ja ;
    skos:definition "WinForms/WPFなどデスクトップアプリで、UIの応答性を保つために画面更新や重い処理の実行場所として意識されるコンテキスト。"@ja ;
    skos:altLabel "UIイベントハンドラ"@ja ;
    ks:uses <https://comcomponent.com/knowledge/synchronizationcontext/> .

<https://comcomponent.com/knowledge/asp-net-core-request-thread/> a skos:Concept ;
    skos:prefLabel "ASP.NET Coreのリクエスト処理"@ja ;
    skos:definition "ASP.NET Coreがリクエストを処理する際のスレッド実行文脈。もともとThreadPool上で動き、SynchronizationContextを持たない。"@ja ;
    skos:altLabel "ASP.NET Coreのスレッド"@ja .

<https://comcomponent.com/knowledge/sync-over-async/> a skos:Concept ;
    skos:prefLabel "同期待ちの混入(sync-over-async)"@ja ;
    skos:definition "非同期処理の継続やワーカーの中で、同期I/OやTask.Result/Wait()のような同期的な待ちを行ってしまうアンチパターン。スレッドプール飢餓の主因になる。"@ja ;
    skos:altLabel "sync-over-async" ;
    ks:mayCause <https://comcomponent.com/knowledge/threadpool-starvation/> .

<https://comcomponent.com/knowledge/threadpool-starvation/> a skos:Concept ;
    skos:prefLabel "スレッドプール飢餓(starvation)"@ja ;
    skos:definition "同期待ちの混入などでスレッドプールのスレッドが塞がり続け、負荷がかかった瞬間に「継続を実行したいのに実行するスレッドがない」状態に陥ること。"@ja ;
    skos:altLabel "Thread Pool Starvation" .

<https://comcomponent.com/knowledge/synchronizationcontext/> a skos:Concept ;
    skos:prefLabel "SynchronizationContext"@ja ;
    skos:definition "awaitした時点の実行コンテキストを表す.NETのクラス。捕捉されると、非同期処理完了後の継続がそのコンテキストへ投げ返される(例: WPF/WinFormsのUIスレッド)。"@ja .

<https://comcomponent.com/knowledge/configureawait-false/> a skos:Concept ;
    skos:prefLabel "ConfigureAwait(false)"@ja ;
    skos:definition "awaitの継続を、捕捉したSynchronizationContextやTaskSchedulerへ投げ返さないことを指示する.NETの記法。「必ずスレッドプールへ移る」保証ではない。"@ja ;
    ks:recommendedFor <https://comcomponent.com/knowledge/generic-library-code/> ;
    ks:notRecommendedFor <https://comcomponent.com/knowledge/ui-thread-context/> .

<https://comcomponent.com/knowledge/generic-library-code/> a skos:Concept ;
    skos:prefLabel "汎用ライブラリコード"@ja ;
    skos:definition "UIやASP.NET Coreなど特定のアプリモデルに依存せず、どちらから呼ばれるか分からない前提で書く再利用可能なコード。"@ja ;
    skos:altLabel "ライブラリコード"@ja .

<https://comcomponent.com/knowledge/cancellationtoken-dotnet/> a skos:Concept ;
    skos:prefLabel "CancellationToken(.NET)"@ja ;
    skos:definition ".NETの協調的キャンセルの仕組み。非同期モードのハンドルへのファイルI/Oでは、内部的にCancelIoExの呼び出しに行き着く。"@ja ;
    skos:altLabel "CancellationToken" .

<https://comcomponent.com/knowledge/async-void/> a skos:Concept ;
    skos:prefLabel "async void"@ja ;
    skos:definition "戻り値を持たないasyncメソッド。呼び出し元がawaitできず、完了を待てず、例外処理が難しくテストもしづらい。"@ja ;
    ks:recommendedFor <https://comcomponent.com/knowledge/event-handler-method/> ;
    ks:notRecommendedFor <https://comcomponent.com/knowledge/regular-async-method/> .

<https://comcomponent.com/knowledge/event-handler-method/> a skos:Concept ;
    skos:prefLabel "イベントハンドラメソッド"@ja ;
    skos:definition "UIフレームワークがシグネチャ上voidを要求する、ボタンクリックなどのイベントに応答するメソッド。"@ja ;
    skos:altLabel "イベントハンドラ"@ja .

<https://comcomponent.com/knowledge/regular-async-method/> a skos:Concept ;
    skos:prefLabel "通常の非同期メソッド"@ja ;
    skos:definition "イベントハンドラ以外の、TaskまたはTask<T>を返す通常の非同期メソッド。"@ja ;
    skos:altLabel "Task/Task<T>を返すメソッド"@ja .

<https://comcomponent.com/knowledge/task-whenall/> a skos:Concept ;
    skos:prefLabel "Task.WhenAll"@ja ;
    skos:definition "複数のTaskを先に全部開始してから、まとめて完了を待つ.NETのAPI。独立した複数処理を直列awaitより効率よくまとめられる。"@ja ;
    ks:recommendedFor <https://comcomponent.com/knowledge/io-bound-operation/> .

<https://comcomponent.com/knowledge/task-whenany/> a skos:Concept ;
    skos:prefLabel "Task.WhenAny"@ja ;
    skos:definition "複数のTaskのうち最初に完了したものを返す.NETのAPI。最初に完了したタスクを返すのであって、最初に成功したタスクを返すのではない。"@ja .

<https://comcomponent.com/knowledge/parallel-foreachasync/> a skos:Concept ;
    skos:prefLabel "Parallel.ForEachAsync"@ja ;
    skos:definition "MaxDegreeOfParallelismで同時実行数の上限を指定しながら、非同期処理を並列に実行できる.NETのAPI。"@ja ;
    ks:recommendedFor <https://comcomponent.com/knowledge/io-bound-operation/> .

<https://comcomponent.com/knowledge/semaphoreslim/> a skos:Concept ;
    skos:prefLabel "SemaphoreSlim"@ja ;
    skos:definition "WaitAsyncで非同期に入り、Releaseで抜ける.NETの同期プリミティブ。並列数の上限指定や、awaitをまたぐ排他制御に使う。"@ja .

<https://comcomponent.com/knowledge/channel-t/> a skos:Concept ;
    skos:prefLabel "Channel<T>"@ja ;
    skos:definition "producer/consumerの形をWriteAsync/ReadAsyncで書けるキュー。境界付き(bounded)にするとbackpressureが働く。"@ja ;
    skos:altLabel "System.Threading.Channels" ;
    ks:recommendedFor <https://comcomponent.com/knowledge/decoupled-background-work/> .

<https://comcomponent.com/knowledge/backpressure/> a skos:Concept ;
    skos:prefLabel "backpressure"@ja ;
    skos:definition "流し込みが速すぎるときに、書き込み側を待たせて増えすぎを防ぐ仕組み。"@ja ;
    skos:altLabel "バックプレッシャー"@ja .

<https://comcomponent.com/knowledge/backgroundservice/> a skos:Concept ;
    skos:prefLabel "BackgroundService"@ja ;
    skos:definition "IHostedServiceの書きやすい実装補助となる抽象クラスで、長く走る本体をExecuteAsyncに書ける。"@ja ;
    skos:altLabel "BackgroundService クラス"@ja ;
    ks:recommendedFor <https://comcomponent.com/knowledge/channel-t/> ;
    ks:implements <https://comcomponent.com/knowledge/ihostedservice/> .

<https://comcomponent.com/knowledge/ihostedservice/> a skos:Concept ;
    skos:prefLabel "IHostedService"@ja ;
    skos:definition ".NETの汎用ホストが、起動時にStartAsync、停止時にStopAsyncを呼んでくれる仕組み。アプリの寿命に合わせて動く常駐処理の入口。"@ja ;
    ks:recommendedFor <https://comcomponent.com/knowledge/asp-net-core-request-thread/> .

<https://comcomponent.com/knowledge/fire-and-forget/> a skos:Concept ;
    skos:prefLabel "fire-and-forget"@ja ;
    skos:definition "呼び出し元が完了を待たない起動方法。例外をどこで見るか、終了時に待つか、件数増加への対応が曖昧になりやすい。"@ja ;
    ks:notRecommendedFor <https://comcomponent.com/knowledge/decoupled-background-work/> .

<https://comcomponent.com/knowledge/decoupled-background-work/> a skos:Concept ;
    skos:prefLabel "呼び出し元から寿命を切り離した背景処理"@ja ;
    skos:definition "メール送信、ログ転送、Webhookの後処理など、今すぐ終わらなくてよいが確実に処理したい仕事を、呼び出し元の寿命から切り離して実行すること。"@ja ;
    skos:altLabel "背景処理の寿命分離"@ja .

<https://comcomponent.com/knowledge/periodictimer/> a skos:Concept ;
    skos:prefLabel "PeriodicTimer"@ja ;
    skos:definition "WaitForNextTickAsyncをawaitして使う、一定間隔の非同期処理向けのタイマー型。1つのタイマーに対して同時に複数のWaitForNextTickAsyncを飛ばさない前提で使う。"@ja ;
    skos:altLabel "System.Threading.PeriodicTimer" ;
    ks:uses <https://comcomponent.com/knowledge/cancellationtoken-dotnet/> .

<https://comcomponent.com/knowledge/iasyncenumerable/> a skos:Concept ;
    skos:prefLabel "IAsyncEnumerable<T>"@ja ;
    skos:definition "全件そろうまで待たず、届いたものから順に非同期に列挙できる.NETのインターフェース。await foreachと組み合わせて使う。"@ja ;
    skos:altLabel "await foreach" ;
    ks:recommendedFor <https://comcomponent.com/knowledge/io-bound-operation/> .

<https://comcomponent.com/knowledge/await-using/> a skos:Concept ;
    skos:prefLabel "await using"@ja ;
    skos:definition "破棄時にフラッシュや通信終了などの非同期処理が必要な型(IAsyncDisposable)を、非同期に破棄するための構文。"@ja ;
    skos:altLabel "IAsyncDisposable" .

<https://comcomponent.com/knowledge/valuetask/> a skos:Concept ;
    skos:prefLabel "ValueTask"@ja ;
    skos:definition "構造体として実装された戻り値型。基本的に1回だけawaitする前提で制約があり、計測して必要性が見えてから選ぶべきとされる。"@ja ;
    skos:altLabel "ValueTask<T>" ;
    ks:notRecommendedFor <https://comcomponent.com/knowledge/regular-async-method/> .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/taskrun-dotnet/> ;
    rdf:predicate ks:notRecommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/io-bound-operation/> ;
    schema:description "既にasyncなI/OをTask.Runで包むのは、I/O待ちを別スレッドへ投げ直しているだけで、整理しづらくなるわりに得がない"@ja ;
    ks:evidence <https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/async-scenarios> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/taskrun-dotnet/> ;
    rdf:predicate ks:recommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/cpu-bound-operation/> ;
    schema:description "Task.Runが効くのは、CPU計算を今のスレッドから外したいときである"@ja ;
    ks:evidence <https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/async-scenarios> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/taskrun-dotnet/> ;
    rdf:predicate ks:recommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/ui-thread-context/> ;
    schema:description "WinForms/WPFなどUIイベントハンドラで重い計算をそのまま回すと画面が止まるため、Task.RunでUIスレッドから計算を外すのが素直である"@ja ;
    ks:evidence <https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/async-scenarios> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/taskrun-dotnet/> ;
    rdf:predicate ks:notRecommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/asp-net-core-request-thread/> ;
    schema:description "ASP.NET Coreのリクエスト処理はもともとThreadPool上で動いているため、Task.Runを挟んで直後にawaitしても余計なスケジューリングが増えるだけになりやすく、基本的に避ける"@ja ;
    ks:evidence <https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/async-scenarios> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/sync-over-async/> ;
    rdf:predicate ks:mayCause ;
    rdf:object <https://comcomponent.com/knowledge/threadpool-starvation/> ;
    schema:description "Task.ResultやWait()のような同期的な待ちがコード中に混入すると、スレッドを塞ぎ続け詰まりやすくなる"@ja ;
    ks:evidence <https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/async-scenarios> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/ui-thread-context/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/synchronizationcontext/> ;
    schema:description "UIスレッドの文脈は、継続をUIスレッドへ戻すための仕組みであるSynchronizationContextとして表される。ConfigureAwait(false)は、awaitが捕捉したこのSynchronizationContextやTaskSchedulerへ継続を戻さないことを指示する記法である"@ja ;
    ks:evidence <https://devblogs.microsoft.com/dotnet/configureawait-faq/> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/configureawait-false/> ;
    rdf:predicate ks:recommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/generic-library-code/> ;
    schema:description "UIやアプリモデルに依存しない汎用ライブラリコードでは、ConfigureAwait(false)は有力な選択肢である"@ja ;
    ks:evidence <https://devblogs.microsoft.com/dotnet/configureawait-faq/> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/configureawait-false/> ;
    rdf:predicate ks:notRecommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/ui-thread-context/> ;
    schema:description "await後にUI更新やアプリ側コンテキストに依存する処理をするなら、ConfigureAwait(false)は付けないほうが自然である"@ja ;
    ks:evidence <https://devblogs.microsoft.com/dotnet/configureawait-faq/> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/io-bound-operation/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/cancellationtoken-dotnet/> ;
    schema:description "新たに設計するI/O待ちのasync APIでは、CancellationTokenを受けてそのまま下流へ渡す設計が基本である(CancellationTokenを持たない既存APIも存在する)"@ja ;
    ks:evidence <https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/async-scenarios> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/async-void/> ;
    rdf:predicate ks:recommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/event-handler-method/> ;
    schema:description "async voidはシグネチャ上voidが必要なイベントハンドラだけで使い、その中でtry/catchにより例外を握ってUI側へ返す"@ja ;
    ks:evidence <https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/async-scenarios> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/async-void/> ;
    rdf:predicate ks:notRecommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/regular-async-method/> ;
    schema:description "async voidは呼び出し元がawaitできず完了を待てず例外処理が難しくテストもしづらいため、イベントハンドラ以外の通常のメソッドでは避けるべきである"@ja ;
    ks:evidence <https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/async-scenarios> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/task-whenall/> ;
    rdf:predicate ks:recommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/io-bound-operation/> ;
    schema:description "独立した複数のI/O待ち処理は、1件ずつawaitするより先に全部開始してTask.WhenAllでまとめて待つほうが素直である"@ja ;
    ks:evidence <https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/async-scenarios> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/task-whenany/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/cancellationtoken-dotnet/> ;
    schema:description "Task.WhenAnyで勝者を選び残りを止めたい実装では、CancellationTokenSourceを使い、勝者が成功と分かってから残りのタスクをキャンセルする"@ja ;
    ks:evidence <https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/parallel-foreachasync/> ;
    rdf:predicate ks:recommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/io-bound-operation/> ;
    schema:description "件数が多いI/O処理では、Task.WhenAllで全件同時に投げるより、Parallel.ForEachAsyncで同時実行数の上限を明示するほうが安定する"@ja ;
    ks:evidence <https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.parallel.foreachasync> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/semaphoreslim/> ;
    rdf:predicate ks:recommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/io-bound-operation/> ;
    schema:description "外部APIへの同時呼び出し数をより自由に制御したい場合、SemaphoreSlimで並列数の上限を作る方法もある"@ja ;
    ks:evidence <https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/async-scenarios> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/channel-t/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/backpressure/> ;
    schema:description "Channel<T>を境界付き(bounded)で作った場合、書き込み側を待たせて増えすぎを防ぐbackpressureが働く。unboundedで使う場合は働かない。backpressure自体はChannel<T>に限らず成り立つ考え方である"@ja ;
    ks:evidence <https://learn.microsoft.com/en-us/dotnet/core/extensions/channels> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/backgroundservice/> ;
    rdf:predicate ks:recommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/channel-t/> ;
    schema:description "Channelに積んだ仕事を順番に処理する専用コンシューマは、アプリの起動・停止に寿命を合わせられるBackgroundServiceに置くことが推奨される"@ja ;
    ks:evidence <https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/backgroundservice/> ;
    rdf:predicate ks:implements ;
    rdf:object <https://comcomponent.com/knowledge/ihostedservice/> ;
    schema:description "BackgroundServiceはIHostedServiceを実装した抽象クラスで、ExecuteAsync(CancellationToken)を1つオーバーライドするだけで常駐ループを書ける"@ja ;
    ks:evidence <https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/fire-and-forget/> ;
    rdf:predicate ks:notRecommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/decoupled-background-work/> ;
    schema:description "Task.Runを投げっぱなしにするfire-and-forgetは、例外をどこで見るか・終了時に待つか・件数増加への対応が曖昧になりやすく、寿命を切り離したい処理には向かない"@ja ;
    ks:evidence <https://learn.microsoft.com/en-us/dotnet/core/extensions/queue-service> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/channel-t/> ;
    rdf:predicate ks:recommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/decoupled-background-work/> ;
    schema:description "呼び出し元から寿命を切り離したい仕事は、Channelに積んで専用のコンシューマが順番に処理する形のほうが例外・停止・上限を管理しやすい"@ja ;
    ks:evidence <https://learn.microsoft.com/en-us/dotnet/core/extensions/channels> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/periodictimer/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/cancellationtoken-dotnet/> ;
    schema:description "PeriodicTimerのWaitForNextTickAsyncはCancellationTokenを受け取り、停止時に素直に使える"@ja ;
    ks:evidence <https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/async-scenarios> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/iasyncenumerable/> ;
    rdf:predicate ks:recommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/io-bound-operation/> ;
    schema:description "ページングされたAPIやストリーミング結果など、全件そろうまで待ちたくない逐次データにはIAsyncEnumerable<T>とawait foreachが向く"@ja ;
    ks:evidence <https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/generate-consume-asynchronous-stream> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/await-using/> ;
    rdf:predicate ks:requires ;
    rdf:object <https://comcomponent.com/knowledge/io-bound-operation/> ;
    schema:description "破棄時にフラッシュや通信終了などの非同期処理が必要な型(IAsyncDisposable)を扱うI/O処理では、usingではなくawait usingを使う(I/O以外のIAsyncDisposable型を扱う場合にも同様に当てはまる)"@ja ;
    ks:evidence <https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-disposeasync> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/valuetask/> ;
    rdf:predicate ks:notRecommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/regular-async-method/> ;
    schema:description "ValueTaskは基本的に1回だけawaitする前提で制約があるため、日常的なアプリコードではまずTask/Task<T>で十分とされ、ValueTaskは計測して必要性が見えてから選ぶ"@ja ;
    ks:evidence <https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.valuetask> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/event-handler-method/> ;
    rdf:predicate ks:requires ;
    rdf:object <https://comcomponent.com/knowledge/ui-thread-context/> ;
    schema:description "async voidのイベントハンドラ(例: SaveButton_Click)はUIスレッドのコンテキストで動作し、await後に_statusLabel.Textのようなコントロール操作を直接行う"@ja ;
    ks:evidence <https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/async-scenarios> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/ihostedservice/> ;
    rdf:predicate ks:recommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/asp-net-core-request-thread/> ;
    schema:description "長い処理やリクエスト寿命から切り離したい処理は、ASP.NET Coreのリクエスト処理の中で抱え込まず、キューやHostedServiceに出すほうが筋がよい"@ja ;
    ks:evidence <https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .
