在FILE_FLAG_WRITE_THROUGH打开的HANDLE上调用WriteFile时何时应该阻塞?

在工作中,我们在Jenkins的帮助下定期在几台机器上运行我们的unit testing。 其中一个unit testing用FILE_FLAG_WRITE_THROUGH打开一个文件,并对该文件进行数以万计的WriteFile调用。 为什么这样做与这个问题无关。 在其中一台机器上,这个testing不断地超时。 经过一番调查后发现,导致这种情况的根本原因是每次调用WriteFile被阻塞(线程被切换出来,并在以后切换),使得testing运行速度大大降低。 奇怪的是,当testing在这台机器上手动启动时, WriteFile没有阻塞,因此testing没有超时。

经过数小时的反复试验,我发现了一个“解决方法”:在受影响的计算机上,如果Jenkins启动了Task Scheduler, WriteFile被阻止,如果手动启动或将BAT文件放入启动文件夹,则不会。 我以为我需要调查更多,所以我创build了一个最小的repro,一个小程序,打开一个文件FILE_FLAG_WRITE_THROUGH ,并随机数据10000次调用WriteFile 。 有了这个最小的repro, WriteFile不断阻塞,不pipe我如何启动它。 我真的很困惑,所以在这里我要求任何解释这种行为。 我所testing的所有机器都具有SATA驱动器,默认设置(写入caching和Windows写入caching刷新启用)。

首先对我来说,甚至没有100%清楚FILE_FLAG_WRITE_THROUGH应该做什么。 互联网上的信息指出,一个特殊的标志被传递到设备,要求它在写入之后刷新其caching。 根据Raymond Chen (以及其他一些人)的说法,现在大多数情况下都是不相关的,因为大多数SATA驱动器由于性能原因而默默地忽略了这个标志。 在“应该或不应该阻止”的一面, 这个页面明确指出,用FILE_FLAG_WRITE_THROUGH WriteFile 应该阻止:

写入调用在数据写入文件之前不会返回。

你有什么想法,为什么我看到这种奇怪的行为(不一致)? 我如何进一步调查?