Asynchronous Windows Phone 8挂在GetFolderAsync和OpenStreamForReadAsync上
我正在制作一个WindowsPhone8应用程序。此应用程序的一部分要求保存状态。我将它保存为一个Json字符串。如果我打开应用程序,保存一些数据,退出应用程序并再次加载,它将挂起GetFolderAsync或OpenStreamForReadAsync。这种情况并非每次都会发生,但一旦它开始挂起,我就必须关闭整个模拟器并制作一个新的模拟器来再次启动应用程序 我甚至尝试过创建一个没有数据的空文件,但问题仍然存在 下面是我用来保存和加载数据的代码。无论我在哪里调用数据加载,无论它是在应用程序启动时还是在表单加载时,它仍然会中断Asynchronous Windows Phone 8挂在GetFolderAsync和OpenStreamForReadAsync上,asynchronous,windows-phone-8,io,Asynchronous,Windows Phone 8,Io,我正在制作一个WindowsPhone8应用程序。此应用程序的一部分要求保存状态。我将它保存为一个Json字符串。如果我打开应用程序,保存一些数据,退出应用程序并再次加载,它将挂起GetFolderAsync或OpenStreamForReadAsync。这种情况并非每次都会发生,但一旦它开始挂起,我就必须关闭整个模拟器并制作一个新的模拟器来再次启动应用程序 我甚至尝试过创建一个没有数据的空文件,但问题仍然存在 下面是我用来保存和加载数据的代码。无论我在哪里调用数据加载,无论它是在应用程序启动时
private async Task SaveLists()
{
//XmlSerializer serializer = new XmlSerializer(typeof(ListHolder));
// Get the local folder.
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
// Create a new folder name DataFolder.
var dataFolder = await local.CreateFolderAsync("DataFolder",
CreationCollisionOption.OpenIfExists);
// Create a new file named DataFile.txt.
var file = await dataFolder.CreateFileAsync("Lists.json",
CreationCollisionOption.ReplaceExisting);
string json = JsonConvert.SerializeObject(Lists, Formatting.Indented);
byte[] fileBytes = System.Text.Encoding.UTF8.GetBytes(json.ToCharArray());
using (var s = await file.OpenStreamForWriteAsync())
{
s.Write(fileBytes, 0, fileBytes.Length);
}
}
private async Task LoadLists()
{
// Get the local folder.
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
if (local != null)
{
try
{
// Get the DataFolder folder.
var dataFolder = await local.GetFolderAsync("DataFolder");
// Get the file.
var files = dataFolder.GetFilesAsync();
var file = await dataFolder.OpenStreamForReadAsync("Lists.json");
string jsonString = "";
// Read the data.
using (StreamReader streamReader = new StreamReader(file))
{
jsonString = streamReader.ReadToEnd();
}
if (jsonString.Length > 0)
{
Lists = JsonConvert.DeserializeObject<List<ItemList>>(jsonString);
}
else
{
Lists = new List<ItemList>();
}
}
catch (Exception ex)
{
Lists = new List<ItemList>();
}
}
}
专用异步任务存储列表()
{
//XmlSerializer serializer=新的XmlSerializer(typeof(ListHolder));
//获取本地文件夹。
StorageFolder local=Windows.Storage.ApplicationData.Current.LocalFolder;
//创建一个新文件夹名DataFolder。
var dataFolder=等待local.CreateFolderAsync(“dataFolder”,
CreationCollisionOption.OpenIfExists);
//创建一个名为DataFile.txt的新文件。
var file=wait dataFolder.CreateFileAsync(“Lists.json”,
CreationCollisionOption.ReplaceExisting);
字符串json=JsonConvert.SerializedObject(列表,格式化,缩进);
byte[]fileBytes=System.Text.Encoding.UTF8.GetBytes(json.tocharray());
使用(var s=await file.OpenStreamForWriteAsync())
{
s、 写入(fileBytes,0,fileBytes.Length);
}
}
专用异步任务加载列表()
{
//获取本地文件夹。
StorageFolder local=Windows.Storage.ApplicationData.Current.LocalFolder;
如果(本地!=null)
{
尝试
{
//获取DataFolder文件夹。
var dataFolder=await local.GetFolderAsync(“dataFolder”);
//获取文件。
var files=dataFolder.getfileasync();
var file=wait dataFolder.OpenStreamForReadAsync(“Lists.json”);
字符串jsonString=“”;
//读取数据。
使用(StreamReader StreamReader=新StreamReader(文件))
{
jsonString=streamReader.ReadToEnd();
}
如果(jsonString.Length>0)
{
Lists=JsonConvert.DeserializeObject(jsonString);
}
其他的
{
列表=新列表();
}
}
捕获(例外情况除外)
{
列表=新列表();
}
}
}
调用结果将导致死锁。我解释了这一僵局并提出了建议。总之,wait
将(默认情况下)尝试在上下文(当前的SynchronizationContext
中恢复执行,除非它是null
,在这种情况下,它使用当前的任务调度器
)
在您的例子中,当前的SynchronizationContext
是UI上下文,它仅由UI线程使用。因此,当您通过调用Result
来阻止UI线程时,async
方法无法安排返回UI线程以完成。您是否检查了文件夹是否确实存在以及是否包含您希望它包含的数据?(我的意思是,手动,而不是编程。)@Richard-你如何调用你的函数?1) Wait LoadLists()
,或2)LoadLists().Wait()
?我的调用是这样的:Wait LoadLists();不幸的是,我看不出这些文件夹和文件是否真的存在,因为它们作为应用程序的一部分存在于手机上。有没有办法不用代码就能看到它们?我确实调用了GetFoldersAsync,我可以在Quickwatch中看到该文件夹window@RichardMannion:您的调用堆栈中是否有等待
或结果
?或者它都是从一个异步void
事件处理程序开始的?谢谢。这似乎解决了问题。在加载数据和GUI实际加载之间仍然存在时间问题,但这应该是可以解决的。我将阅读你的博客,谢谢。为此,我建议你有目的地为你的UI设计一个“加载”状态,让你的初始加载开始于该状态,并在数据加载时转换状态。如果您使用MVVM,我编写了一个基本上允许您将数据绑定到任务
结果(并在任务
完成时获取INotifyPropertyChanged
事件)的脚本。