逾時
通訊資源的句柄有一組相關聯的逾時參數,會影響讀取和寫入作業的行為。 逾時可能會導致 ReadFile、ReadFileEx、WriteFile 或 WriteFileEx 作業在逾時間隔經過時結束,即使指定的字元數目尚未讀取或寫入也一樣。 當讀取或寫入作業期間發生逾時時時,它不會被視為錯誤(也就是讀取或寫入函式的傳回值表示成功)。 實際讀取或寫入的位元組計數是由 ReadFile 或 WriteFile 所報告(或由 GetOverlappedResult 或 FileIOCompletionRoutine 函式所報告,如果 I/O 是以重疊的作業執行)。
當應用程式開啟通訊資源時,系統會將資源的逾時值設定為上次使用資源時生效的值。 如果從未開啟通訊資源,系統會將逾時值設定為某些預設值。 不論是哪一種情況,應用程式都應該在開啟資源之後一律判斷目前的逾時值,然後明確設定它們以符合其需求。 若要判斷通訊資源的目前逾時值,請使用 GetCommTimeouts 函 式。 若要變更逾時值,請使用 SetCommTimeouts 函 式。
逾時參數會啟用兩種類型的逾時。 當收到任何兩個字元之間的時間超過指定的毫秒數時,就會發生時間間隔逾時。 計時會在收到第一個字元時開始,並在收到每個新字元時重新啟動。 讀取作業所耗用的總時間超過計算的毫秒數時,就會發生總逾時。 當 I/O 作業開始時,計時會立即啟動。 寫入作業僅支援總逾時。 讀取作業同時支援間隔和總逾時,這兩者可以分開使用或合併。
讀取或寫入作業的總逾時期間,以毫秒為單位,是使用 GetCommTimeouts 或 SetCommTimeouts 函式中所指定之 COMMTIMEOUTS 結構的乘數和常數值來計算。 使用下列公式:
Timeout = (MULTIPLIER * number_of_bytes) + CONSTANT
使用乘數和常數可讓總逾時期間根據所要求的數據量而有所不同。 應用程式只能藉由將乘數設定為零來使用常數,或只使用乘數將常數設定為零。 如果常數和乘數都是零,就不會使用總逾時。
如果所有讀取逾時參數都為零,則不會使用讀取逾時,而且讀取作業不會完成,直到讀取要求的位元元數目或發生錯誤為止。 同樣地,如果所有寫入逾時參數都是零,則在寫入要求的位元元組數目或發生錯誤之前,不會完成寫入作業。
如果讀取間隔逾時參數是 MAXDWORD 值,而且讀取總逾時參數都是零,則讀取作業會在讀取輸入緩衝區中可用的字元之後立即完成,即使它是空的。
間隔計時會強制讀取作業在接收時返回。 使用間隔逾時的程式可以設定相當短的間隔參數,因此它可以快速回應一或幾個字元的小型隔離高載,但是當數據在穩定數據流中收到數據時,仍然可以使用單一呼叫來收集大型字元緩衝區。
當某種流量控制封鎖傳輸或呼叫 SetCommBreak 函式以暫停字元傳輸時,寫入作業的逾時可能會很有用。
下表摘要說明讀取作業的行為,其依據為總計和間隔逾時所指定的值。
總數 | 間隔 | 行為 |
---|---|---|
0 | 0 | 當緩衝區完全填滿時傳回 。 不使用逾時。 |
T | 0 | 當緩衝區已完全填滿,或自作業開始時已經過 T 毫秒時傳回 。 |
0 | Y | 當緩衝區完全填滿或 Y 毫秒在收到任何兩個字元之間時傳回 。 在收到第一個字元之前,時間才會開始。 |
T | Y | 當緩衝區完全填滿或發生任一類型的逾時時時,傳回 。 |
注意
不過,該時間是相對於控制實體裝置的系統。 對於數據機之類的遠端裝置,計時會相對於數據機所連接的伺服器系統。 任何網路傳播延遲都不會納入考慮。 例如,用戶端應用程式可能會指定計算為500毫秒的總逾時。 當伺服器經過 500 毫秒時,就會傳回逾時錯誤給用戶端。 如果有 50 毫秒的網路傳播延遲,用戶端將不會收到逾時通知,直到實際發生逾時大約 50 毫秒為止。
注意
逾時參數會影響通訊裝置上重迭讀取和寫入作業的行為。 使用重疊的 I/O,ReadFile、WriteFile、ReadFileEx 或 WriteFileEx 函式可以在作業完成之前傳回。 逾時參數可以判斷作業何時完成。