2016-05-12 66 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