Windows 8 从App.OnSuspending调用StorageFolder.CreateFileAsync时崩溃
我的Win RT应用程序在Windows 8 beta版上与VS2012RC配合使用,现在在visual studio和Windows 8 pro的最终版本中遇到了一个问题,即仅当我将调试器断点设置为文件创建方法时,才能在OnSuspend中创建/打开文件Windows 8 从App.OnSuspending调用StorageFolder.CreateFileAsync时崩溃,windows-8,visual-studio-2012,async-await,windows-store,Windows 8,Visual Studio 2012,Async Await,Windows Store,我的Win RT应用程序在Windows 8 beta版上与VS2012RC配合使用,现在在visual studio和Windows 8 pro的最终版本中遇到了一个问题,即仅当我将调试器断点设置为文件创建方法时,才能在OnSuspend中创建/打开文件 private void OnSuspending(object sender, SuspendingEventArgs e){ var deferral = e.Suspending
private void OnSuspending(object sender, SuspendingEventArgs e){
var deferral = e.SuspendingOperation.GetDeferral();
if (null != m_document) Save();
deferral.Complete();
}
async void Save(){
var folder = KnownFolders.DocumentsLibrary;
var file = await folder.CreateFileAsync(GetFileName(),Windows.Storage.CreationCollisionOption.ReplaceExisting);
var xDoc = GetXDocument();
using (var stream = await file.OpenStreamForWriteAsync()){
xDoc.Save(stream);
}
}
- 如果我在
),调试器将输入 继续,一切正常StorageFile=wait上设置断点 folder.CreateFileAsync(…
- 但是,如果我不设置断点,文件将被创建,但是 不会保存xml的内容(文件为空)
- 如果我在
行)下面设置断点,调试器将永远不会进入StorageFile file=await folder.CreateFileAsync(…
有人有什么想法吗?我还测试了一个使用
文件夹的版本。OpenStreamForWriteAsync
,效果非常相似。你的时间不多了。开始时大约有5秒,但如果你不声明你将使用它,那么你的时间就会缩短。试试这个:
private async void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
try
{
await Task.Delay(1000);
Debug.WriteLine("Done");
}
finally
{
deferral.Complete();
}
}
有关更多详细信息,请参阅。有关正式文档,请参阅:
请注意,当应用程序正在运行时,是否需要执行异步工作
暂停您需要将暂停的完成推迟到
您的工作已完成。您可以在
SuspendingOperation对象(可通过事件参数获得)延迟
在调用
返回了SuspendingDeleral对象
问题是对Save方法的调用。只等待了第一部分(文件的创建),第二部分(保存XML)是异步完成的,因此挂起操作的延迟直到保存过程结束 避免此问题的一个可能解决方案是明确等待保存操作的完成。这可以通过将OnSuspending方法声明为
aysnc
,然后使用wait关键字等待保存操作的完成来实现(请注意保存方法的任务返回类型)
我希望这篇文章能帮助其他陷入同样陷阱的人(我想知道为什么w8的beta版没有出现问题,但我认为MS已经优化了应用程序终止过程,因此在暂停过程之后,没有太多时间进行意外工作)…是否完成操作的时间不够了?@mydogisbox:似乎是。但我不知道为什么。Save()中的wait命令似乎不是等到创建时才执行,而是立即返回(或在文件创建后执行)这也是我看到的,如果我在每次方法调用之后添加Debug.WriteLine-calls。如果没有断点,代码将永远不会到达“var xDox=GetXDocument()”-调用。它在创建文件后返回(但没有异常)。谢谢你的回答!遗憾的是,这并不能解决问题。如果你看我的代码示例,我已经推迟了暂停,我只是为了示例的简单性删除了所有异常处理。但是这没有什么区别。我发现了问题。请看我的答案,再次感谢你的帖子。@HCL我给出的解决方案是w你需要什么…我只是无意中遗漏了两个关键部分…我现在把它们放回了。别忘了在最后调用
deleral.Complete();
。@mydogisbox:谢谢,但是“delerall.Commit()”始终在,请看OnSuspend的实现。我只是删除了try/finally以使示例更小。问题不在于XML的完整性,而在于XML的序列化。在我的初始例程(Save)中,我没有注意到该方法将部分执行异步(请参阅“wait folder.Create…”后面的代码)。解决方案是等待整个方法完成(请参阅OnSuspending中的wait和Save()的返回类型“Task”)。
private async void OnSuspending(object sender, SuspendingEventArgs e){
var deferral = e.SuspendingOperation.GetDeferral();
if (null != m_document) await Save();
deferral.Complete();
}
async Task Save(){
var folder = KnownFolders.DocumentsLibrary;
var file = await folder.CreateFileAsync(GetFileName(),Windows.Storage.CreationCollisionOption.ReplaceExisting);
var xDoc = GetXDocument();
using (var stream = await file.OpenStreamForWriteAsync()){
xDoc.Save(stream);
}
}