• システム開発に関わる内容をざっくりと書いていく

C# TimeoutException / 操作タイムアウトの切り分け

TimeoutException や「操作がタイムアウトしました」系は、どこで時間切れになったかの特定が先。HttpClient・DB・自前の Wait で原因が違う。

先に結論

  • スタックトレースと例外型でどの API が切ったかを見る
  • HTTP なら HttpClient.Timeout / サーバ側 / プロキシのどれか
  • DB ならコマンドタイムアウトと接続タイムアウトを分ける
  • TaskCanceledException と混同しやすい。キャンセルと時間切れを切り分ける

よくある発生源

  • HttpClient(既定 100 秒)や CancellationTokenSource.CancelAfter
  • ADO.NET / EF のコマンドタイムアウト
  • WaitAsync(timeout) / SemaphoreSlim 等の自前制限
  • 外部 SDK(クラウド・決済)のクライアント設定

切り分け手順

  1. 例外型とメッセージ(Timeout / canceled / expired)を控える
  2. スタックの一番外側の自前コード行を特定
  3. その呼び出しのタイムアウト設定値をコードと設定ファイルで確認
  4. 遅いのは相手側か、自プロセスの詰まり(スレッド・ロック)かをログ時刻で見る
  5. 値を闇雲に延ばす前に、遅い原因(N+1、ロック、DNS)を疑う

対策の型

  • 適切なタイムアウト + リトライ(べき等な操作のみ)
  • CancellationToken を下流まで渡す
  • HTTP は IHttpClientFactory で Timeout を集約
  • 失敗時は「何秒で・どの操作が」をログに残す

関連: HttpClient タイムアウト / ソケット枯渇

ざっくりまとめ

  • 誰が切ったかを例外とスタックで特定
  • HTTP / DB / 自前を分けて設定を見る
  • 延長だけでは再発する。遅さの原因もセットで見る

関連記事