2016-05-12 64 views
0

我正在將數據定期保存到文件中(每次打開和關閉文件),我想使用Stopwatch來測量文件操作所花費的時間。關閉流阻塞線程嗎?

我是否應該納入Close()所需的測量時間?


我們有軟件的問題,我懷疑文件操作,例如,繁忙的硬盤或某種可能導致延遲的故障。在這種情況下,調用Close()會導致延遲(阻塞)還是Close()一種非阻塞方法(但是在框架/ winapi文件內部的深處將從寫入緩衝區等刷新到其後)?

或者可能Write()在失敗的情況下會變慢?我不知道如何模擬磁盤問題來快速測試會發生什麼。

+1

要麼關閉文件的時間太短而不重要,要麼不是。你打算如何在沒有測量的情況下找出哪些是真的? –

+1

您無法獲得有意義的測量結果。您從不直接寫入磁盤,而是寫入文件系統緩存。內存到內存的拷貝速度非常快。在你關閉文件很久以後,它會被懶惰地寫入磁盤。這*可能會出錯,發生在文件系統緩存滿容量時。無論是因爲寫的太多還是因爲其他程序的原因,或者是因爲計算機沒有足夠的內存或磁盤太慢或碎片太多。您的寫入()將被阻止,直到空間釋放,這可能需要一段時間。非常隨機,很難預測。 –

+0

一旦我將記錄器配置爲每次寫入消息時都會打開/關閉文件,並且顯示出一個非常奇怪的問題:在這種情況下,寫入消息的時間與日誌文件大小成比例增長。偶爾寫一條消息需要0.3秒。保持FileStream立即打開,性能大大提高(寫入消息的時間變得不變,而不取決於文件大小)。所以我懷疑文件上的打開/關閉操作是默認同步的(我聽說.NET 5有異步類似物)。所以如果你知道你需要這個文件並且經常寫,我建議試着保持它打開。 –

回答

-1

首先,the documentation for FileStream建議調用Dispose而不是Close。檢查參考源,所有Close所做的是:

Dispose(true); 
GC.SuppressFinalize(this); 

將調用Close()在這種情況下會導致的延遲(粘連)或是 關閉()非阻塞方法(但深的某處內 框架/ winapi文件正在從寫入緩衝區等被刷新,等 它)?

Close電話Dispose,它做了兩兩件事:

  1. 關閉文件句柄。
  2. 刷新任何掛起的寫入磁盤(默認情況下,寫入被緩存)。

當然,「刷新任何掛起的寫入到磁盤」的意思是告訴操作系統「刷新任何掛起的寫入到磁盤」。根據各種因素,操作系統的處理方式不同(例如,USB驅動器傾向於寫得不那麼懶惰,臨時文件可能永遠不會刷新到磁盤)。

+0

不是我的失望,但你沒有回答我的問題:是否調用'Close'阻止呼叫者(我覺得你在說'不')? @HansPassant評論解釋了什麼'Write'會在發生問題時阻止調用者。 – Sinatr