我正在尝试写入一个文件,但“偶尔”我遇到的问题我认为归结为并发性,因为某些当时,我得到了{{1}带消息:
访问被拒绝。 (HRESULT异常:0x80070005(E_ACCESSDENIED))
......来自以下内容:
System.UnauthorizedAccessException
我只能假设这是一些并发性,或者它仍然可以在其他地方读取,但我似乎找不到等待它可用的方法 - 我通常会{{1围绕它,但public async void SubmitChanges()
{
DataContractSerializer serializer =
new DataContractSerializer(typeof(LocalCache<T>));
StorageFile file = await ApplicationData.Current.LocalFolder
.CreateFileAsync(GetFileNameForType(),
CreationCollisionOption.ReplaceExisting);
//Occasionally throws here
using (var fi = await file.OpenTransactedWriteAsync())
{
serializer.WriteObject(fi.Stream.AsStreamForWrite(), this);
await fi.CommitAsync();
}
}
不允许这样做,那么其他选项是什么?
答案 0 :(得分:6)
通常,在上一个操作完成之前,您不会开始下一个操作。
提示:避免async void
;请改用async Task
。这使您可以知道上一个操作何时完成。
答案 1 :(得分:1)
这里可能会发生很多事情。正如Stephen上面提到的,封装方法不会返回任务。这意味着无论调用 SubmitChanges 的方法是什么,都会使用“fire and forget”模式调用它,并且可以并行运行此调用之后的代码。这可能不是你想要的。
此外,我注意到您正在使用 StorageFile.OpenTransacted 。我以前没有使用过这个,但是注释表明只支持ReplaceFile的操作系统支持OpenTransacted。此功能字面上允许新文件承担旧文件的标识,但我很确定如果旧文件打开,操作将失败。
我不认为交换文件标识的尝试会在交易文件关闭之前发生,这会发生在 Dispose 上,由于使用会自动发生声明,这是你有时会看到异常的那一行。
我建议你改回一个Task,我也会考虑使用常规的 StorageFile.OpenAsync 。