Skip to content

MS_WCFTimeout

nishi_74322014 edited this page Sep 1, 2026 · 1 revision

WCFのタイムアウト

概要

WCF のタイムアウトについてまとめてみた。

詳細

WCF では、Binding でタイムアウト設定が可能。

クライアント側

概要

  • SendTimeout
    • OperationTimeout の初期化に使用。
    • メッセージの送信プロセス全体を制御。
      • 要求/応答サービス操作の応答メッセージの受信
      • コールバック コントラクト メソッドから応答メッセージを送信
  • ReceiveTimeout
    使用されない。
  • OpenTimeout
    明示的なタイムアウト値が指定されていない場合、チャネルを開くときに使用。
  • CloseTimeout
    明示的なタイムアウト値が指定されていない場合、チャネルを閉じるときに使用。

補足(SendTimeout が「送信」だけではない点が要点): 名前から
「送信にかかる時間の上限」と読んでしまいがちだが、
本文が明記しているとおり
応答メッセージの受信までを含む
すなわち、要求/応答型の呼び出しでは
**実質的にこれが「呼び出し全体のタイムアウト」**である。

「サーバの処理が重いのでタイムアウトを延ばしたい」という場合に
変更すべきなのは SendTimeout であり、
ReceiveTimeout ではない。
クライアント側の ReceiveTimeout は使われない(本文のとおり)ため、
ここを延ばしても何も変わらない、というのが典型的な躓きどころである。

各既定値は次のとおり(いずれも Binding の既定)。

プロパティ 既定値 効く場面
OpenTimeout 1 分 チャネルを開く(接続確立、セキュリティ ネゴシエーション)
SendTimeout 1 分 呼び出し全体(応答受信まで)
ReceiveTimeout 10 分 サーバ側でのアイドル セッションの維持時間
CloseTimeout 1 分 チャネルを閉じる

なお、ReceiveTimeout は「使われない」のではなく
サーバ側で意味を持つ(後述)。

サーバ側

概要

  • 検証した所、executionTimeout は効いてない模様。
  • クライアント側のタイムアウト設定しかないが、
    サーバ側プログラムから OperationTimeout に設定が可能。
    (既定で、クライアント側の SendTimeout 設定をサーバ側の OperationTimeout 設定の初期値に設定している)

補足(executionTimeout が効かない理由): httpRuntime
executionTimeoutASP.NET のパイプライン
要求の実行時間を制限する設定である。
これが WCF に効かないのは、次の 2 つの理由による。

  1. executionTimeoutdebug="true" のとき無効になる
    compilation debug="true" だと ASP.NET はタイムアウトを適用しない)。
    検証環境で「効かない」と見えるのは、多くの場合これが原因である。
  2. WCF を ASP.NET 互換モードaspNetCompatibilityEnabled="true")で
    動かしていない場合、要求は ASP.NET のパイプラインではなく
    WCF 自身のディスパッチャが処理するため、
    httpRuntime の設定が適用されない。

したがって、本文の「効いてない模様」は
設定ミスではなく仕様どおりである。

サーバ側で処理時間そのものを打ち切りたい場合は、
WCF のタイムアウト設定ではなく
業務処理側にキャンセル機構を実装するCancellationToken 等)か、
DB 側のタイムアウト
SQL Server でのロック・タイムアウト)で
上限を設けることになる。

補足(サーバ側で意味を持つタイムアウト): サーバ側の Binding では、
次の 2 つが実際に効く。

設定 サーバ側での意味
ReceiveTimeout セッションのアイドル タイムアウト。この時間クライアントから何も来なければセッションを破棄する
OpenTimeout / CloseTimeout チャネルの開閉

ReceiveTimeout の既定は 10 分と長めであるため、
セッション有りのバインディング(netTcpBinding
wsHttpBinding の信頼できるセッション等)では、
切断されたクライアントのセッションが 10 分間残り続ける
同時接続数の上限(ServiceThrottlingMaxConcurrentSessions)と
併せて考慮しないと、
接続できなくなるという形で問題が表面化する。

補足(タイムアウトは「多層」であることを忘れない): WCF の呼び出しでは、
実際には複数のタイムアウトが重なっている。

ブラウザ/呼び出し元
  └ ASP.NET executionTimeout(呼び出し元が Web アプリの場合)
      └ WCF SendTimeout ← 呼び出し全体
          └ HTTP/TCP の接続タイムアウト
              └ サーバ側の業務処理
                  └ SqlCommand.CommandTimeout(既定 30 秒)
                      └ SQL Server のロック タイムアウト

内側ほど短くなっていないと、
外側が先に諦めて内側の処理は動き続ける(孤児処理)ことになる。
DB の更新処理では、これが
ロックを掴んだまま放置される原因になり得る
SQL Server でのデッドロック)。
設計時には各層の値を一覧にして、
内側 < 外側の関係を確認しておくこと。

参考

クライアント側の参考

参考

設定・実装の例@Open棟梁

クライアント

設定

https://github.com/OpenTouryoProject/OpenTouryo/blob/master/root/programs/CS/Samples/WebApp_sample/WebForms_Sample/WebForms_Sample/Web.config#L235

実装

サーバ

設定

https://github.com/OpenTouryoProject/OpenTouryo/blob/master/root/programs/CS/Frameworks/Infrastructure/ServiceInterface/ASPNETWebService/ASPNETWebService/Web.config#L215

移行メモ(構成): 原典ではクライアント側の参考リンクが
「クライアント側」節の中にあったが、
サーバ側の参考節と並ぶ位置に整理した(内容は同一)。

補足(最新化:WCF の現在): WCF は .NET Framework 限定の技術であり、
.NET Core 以降にはサーバ側が移植されていない
新規開発では次が後継となる。

用途 後継
HTTP ベースのサービス ASP.NET Core Web APIWebAPI
高性能な RPC gRPC
既存 WCF の移植 CoreWCF(コミュニティ主導、Microsoft 支援)

なお、クライアント側System.ServiceModel.* パッケージ)は
.NET Core / .NET 5 以降でも利用可能であり、
既存の WCF サービスを呼ぶことはできる。
その場合も本ページのタイムアウト設定はそのまま有効である。


Tags: 移行, .NET開発, 通信技術

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally