有时保存的文件只包含NUL字符

Boj*_*ojo 6 c# async-await windows-runtime winrt-async

我们的Windows 8.1应用程序(WinRT)中存在一个问题,即有时我们保存的文件已损坏.这些文件的文件大小正确,但该文件只包含NUL字符.该文件应包含一个序列化对象作为XML.

为了找到问题,我们不会覆盖该文件,我们执行以下操作:

  1. 将当前对象序列化为临时文件.
  2. 检查临时文件的内容
  3. 复制当前文件(到.timestamp.xml.bak)
  4. 将临时文件移动/替换为当前文件

大多数情况下,一切正常,但有时.timestamp.xml.bak文件和内容文件损坏.除此之外,日志文件也会损坏(也只有NUL字符).整个文件由NUL字符组成.当我查看bak文件和主文件的踪迹时,我看到主文件的大小增加了.这应该是正确的,因为添加了一个新的XML元素.但它不包含XML.

我不知道这是怎么发生以及为什么会发生这种情况.它发生在大约5%的文件中,应该进行编辑,每个损坏的文件在5-20次保存尝试后发生.它也发生在几个平板电脑上.

以下是创建损坏文件的代码片段:

StorageFile file = await lDataFld.CreateFileAsync(filename + ".tmp",  CreationCollisionOption.OpenIfExists);

StorageFile oldFile = await dataFld.GetFileAsync(filename + ".xml");
if (oldFile != null)
{
await oldFile.CopyAsync(dataFld, string.Format("{0}.{1}.xml.bak", filename, DateTime.Now.ToString("yyyyMMddHHmmssfffffff")), NameCollisionOption.ReplaceExisting);
}
await file.MoveAndReplaceAsync(await dataFld.GetFileAsync(filename + ".xml"));

Logger.Log(string.Format("Saved {0}.", filename));
Run Code Online (Sandbox Code Playgroud)

有人能告诉我我们如何最终得到只包含NUL字符的文件以及如何/为什么会发生这种情况?甚至可以更好地修复它.

一个小小的问题:我们不能以任何方式重现这个问题,它只发生在我们的生产环境中.

Sha*_*ell 3

我能想到可能产生这种结果的唯一原因是:

  • 文件写入过程中操作系统硬崩溃(BSOD)
  • 应用程序在文件写入过程中终止

我猜这是第二个原因。

考虑到这一点以及您说它是一个 Windows 运行时应用程序的事实,并且我猜测该应用程序没有被手动终止,我的猜测是它与Windows 运行时生命周期有关。鉴于 UWP 应用程序在进入后台时可以“挂起”,然后可以在“挂起”模式下随时被操作系统终止(与 Android 或 IOS 等移动操作系统非常相似)。

因此,鉴于此,我的猜测是您的应用程序在挂起之前启动异步操作,然后在完成文件写入之前挂起/终止。

解决方法是确保您将应用程序标记为在执行文件写入时正在执行“后台”工作,以便操作系统不会在文件写入期间暂停您。几乎所有移动操作系统都具有这种类型的功能,允许您稍微“超速”,以确保您可以在应用程序暂停/终止之前完成工作。对于 UWP 应用程序,请查看后台任务或研究如何处理应用程序挂起/推迟应用程序挂起