タイムアウト

通信リソースへのハンドルには、読み取り操作と書き込み操作の動作に影響を与えるタイムアウト パラメーターのセットが関連付けられています。 タイムアウトすると、指定された文字数の読み取りまたは書き込みが行われていなくても、タイムアウト間隔が経過すると、ReadFileReadFileExWriteFileEx、または WriteFileEx 操作が終了する可能性があります。 読み取りまたは書き込み操作中にタイムアウトが発生した場合、エラーとして扱われません (つまり、読み取りまたは書き込み関数の戻り値は成功を示しています)。 読み取りまたは書き込みされた実際のバイト数は、ReadFile または WriteFile によって報告されます (I/O が重複する操作として実行された場合、GetOverlappedResult または FileIOCompletionRoutine 関数によって報告されます)。

アプリケーションが通信リソースを開くと、システムはリソースのタイムアウト値を、リソースが前回使用されたときに有効な値に設定します。 通信リソースが開かれていない場合、タイムアウト値が既定値に設定されます。 どちらの場合も、アプリケーションは、リソースを開いた後、必ず現在のタイムアウト値を判別し、その要件を満たすよう明示的に設定する必要があります。 通信リソースの現在のタイムアウト値を判別するには、GetCommTimeouts 関数を使用します。 タイムアウト値を変更するには、SetCommTimeouts 関数を使用します。

タイムアウト パラメーターにより、2 種類のタイムアウトが有効になります。 間隔タイムアウトは、任意の 2 文字の受信までの時間が指定されたミリ秒を超えたときに発生します。 タイミングは、最初の文字が受信されたときに開始され、新しい各文字が受信されたときに再起動されます。 合計タイムアウトは、読み取り操作によって消費された時間の合計が、計算されたミリ秒を超えた場合に発生します。 I/O 操作が開始されると、すぐにタイミングが開始します。 書き込み操作では、合計タイムアウトのみサポートされます。 読み取り操作では、間隔と合計タイムアウトの両方がサポートされます。これは別個に使用することも、組み合わせて使用することもできます。

読み取りまたは書き込み操作の合計タイムアウト時間 (ミリ秒単位) は、GetCommTimeouts 関数または SetCommTimeouts 関数で指定された COMMTIMEOUTS 構造の乗数と定数値を使用して計算されます。 次の式が使用されます。

Timeout = (MULTIPLIER * number_of_bytes) + CONSTANT

乗数と定数の両方を使用すると、要求されるデータの量に応じて、合計タイムアウト期間が変化します。 アプリケーションでは、乗数を 0 に設定することにより定数のみを使用するか、定数を 0 に設定することにより乗数のみを使用することができます。 定数と乗数の両方が 0 の場合、合計タイムアウトは使用されません。

すべての読み取りタイムアウト パラメーターが 0 の場合、読み取りタイムアウトは使用されず、要求されたバイト数が読み取られるかエラーが発生するまで読み取り操作は完了しません。 同様に、すべての書き込みタイムアウト パラメーターが 0 の場合、要求されたバイト数が書き込まれるかエラーが発生するまで書き込み操作は完了しません。

読み取り間隔のタイムアウト パラメーターが MAXDWORD 値で、読み取りの合計タイムアウト パラメーターがどちらも 0 の場合、読み取り操作は、空の場合でも、入力バッファーで使用可能な文字を読み取った直後に完了します。

間隔のタイミングは、受信が一時停止すると読み取り操作を強制的に戻します。 間隔タイムアウトを使用するプロセスでは、かなり短い間隔パラメーターを設定できるため、1 文字または数文字の小さい分離バーストにすばやく応答できますが、安定したストリームでデータを受信したときでも、1 回の呼び出しで大きな文字バッファーを収集できます。

書き込み操作のタイムアウトは、何らかのフロー制御によって送信がブロックされている場合や、SetCommBreak 関数が呼び出されて文字の転送を中断する場合に役立ちます。

次の表は、合計タイムアウトと間隔タイムアウトに指定された値に基づく、読み取り操作の動作をまとめたものです。

小計 Interval Behavior
0 0 バッファーがいっぱいになると返されます。 タイムアウトは使用されません。
T 0 バッファーがいっぱいになったとき、または操作の開始から T ミリ秒が経過したときに返されます。
0 バッファーがいっぱいになったとき、または任意の 2 文字の受信の間に Y ミリ秒が経過したときに返されます。 最初の文字が受信されるまで、タイミングは開始しません。
T バッファーがいっぱいになったとき、またはいずれかの種類のタイムアウトが発生したときに返します。

 

Note

ただし、そのタイミングは、物理デバイスを制御するシステムが基準となります。 モデムなどのリモート デバイスの場合、タイミングはモデムが接続されているサーバー システムが基準となります。 ネットワーク伝達の遅延は考慮されません。 たとえば、クライアント アプリケーションでは、500 ミリ秒を計算する合計タイムアウトを指定できます。 サーバーで 500 ミリ秒が経過すると、タイムアウト エラーがクライアントに返されます。 50 ミリ秒のネットワーク伝達遅延がある場合、タイムアウトが実際に発生してから約 50 ミリ秒後までクライアントにタイムアウトが通知されません。

 

Note

タイムアウト パラメーターは、通信デバイスでの読み取りおよび書き込みの重複操作の動作に影響を与えます。 I/O が重複している場合、ReadFileWriteFileReadFileEx、または WriteFileEx 関数は、操作が完了する前に返すことができます。 タイムアウト パラメーターは、操作が完了したタイミングを判断できます。