前提条件:Windows 8 Pro RTM + VS2012 Ultimate RTM
1.以下代码在App.xaml.cs中。 如果用户第一次打开此应用程序,该应用程序将创建一个xml。
private async void CheckXML()
{
try
{
StorageFile file1 = await ApplicationData.Current.LocalFolder.GetFileAsync("BetterTask.xml");
}
catch (FileNotFoundException)
{
CreateXML();
}
}
private async void CreateXML()
{
StorageFile file2 = await ApplicationData.Current.LocalFolder.CreateFileAsync("BetterTask.xml", CreationCollisionOption.ReplaceExisting);
using (var writeStream1 = await file2.OpenStreamForWriteAsync() as Stream)
{
XDocument doc1 = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement("tasks",
new XElement("task",
new XElement("title", "Wish you enjoy this App :)"),
new XElement("due", DateTime.Now.Date.ToString("yyyy/MM/dd")))));
doc1.Save(writeStream1);
await writeStream1.FlushAsync();
}
}
2.当应用程序启动时,在MainPage.xaml中的OnNavigatedTo事件中,它将读取xml以检索数据。
protected override void OnNavigatedTo(NavigationEventArgs e)
{
ReadTasks("all");
ShowTime();
}
private async void ReadTasks(string action)
{
StorageFile file1 = await ApplicationData.Current.LocalFolder.GetFileAsync(xmlfilename);
var ReadStream1 = await file1.OpenStreamForReadAsync() as Stream;
XDocument doc1 = new XDocument();
doc1 = XDocument.Load(ReadStream1);
ReadStream1.Dispose();
.......
}
0.3。 发生了什么:当应用首次启动时,以下代码会引发错误:
var ReadStream1 = await file1.OpenStreamForReadAsync() as Stream;
错误: 用户代码未处理UnauthorizedAccessException 访问被拒绝。 (HRESULT异常:0x80070005(E_ACCESSDENIED))
I check the folder, the xml file is created when the error happen.
0.4。 更多东西:当我重新打开应用程序时,没有任何反应,它就像一个魅力。我不知道为什么,该应用程序在Win8 RP和VS 2012 RC中运行良好。我什么都没改,但为什么它不能在带有VC2012 RTM的Win8 RTM中运行
答案 0 :(得分:1)
由于您的第二个代码块使用变量名 xmlfilename ,我不知道您是否正在尝试打开同一个文件,但我猜你是。由于在App.xaml.cs中创建文件的操作和在MainPage.xaml.cs中读取文件的操作都是异步的,因此它们可能同时发生。解决此问题的最简单方法是使用表示XML文件创建的应用程序级Task变量。像这样:
Task creatingFile = CheckXML();
createFile.Start();
现在,在您的MainPage.xaml文件中,您可以使用 creatingFile.IsCompleted (或 IsFaulted )来检查任务是否仍在运行。如果任务完成,那么您只需打开该文件即可。如果任务尚未完成,您可以使用 creatingFile.ContinueWith(...)来安排文件在创建后打开。
另外,不要忘记在using语句中包装文件,以确保在使用它们时它们已关闭。像这样:
using (var ReadStream1 = await file1.OpenStreamForReadAsync() as Stream)
{
...
}
答案 1 :(得分:1)
Jared在同一时间完成此操作是正确的,但我不太喜欢应用程序范围的任务参考。发生这种情况的原因是因为您无法等待返回void的方法。您已将方法CheckXML
和CreateXML
标记为async void。异步void方法是一种“即发即弃”的方法。您的代码将异步执行它。当您导航到页面时,它会尝试阅读它。
我建议创建一个读取文件的方法,如果文件只是读取,则先创建然后再读取。
选项1:
private async void ReadTasks(string action)
{
// This is a fire and forget method
StorageFile file = await GetXmlFile(xmlfilename);
var ReadStream1 = await file.OpenStreamForReadAsync() as Stream;
XDocument doc1 = new XDocument();
doc1 = XDocument.Load(ReadStream1);
ReadStream1.Dispose();
.......
}
private async Task<StorageFile> GetXmlFile(string xmlfilename)
{
try
{
StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync(xmlfilename);
}
catch (FileNotFoundException)
{
file = await CreateXml(xmlfilename);
}
return file;
}
private async Task<StorageFile> CreateXML(string xmlfilename)
{
StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(xmlfilename, CreationCollisionOption.ReplaceExisting);
using (var writeStream1 = await file2.OpenStreamForWriteAsync() as Stream)
{
XDocument doc1 = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement("tasks",
new XElement("task",
new XElement("title", "Wish you enjoy this App :)"),
new XElement("due", DateTime.Now.Date.ToString("yyyy/MM/dd")))));
doc1.Save(writeStream1);
await writeStream1.FlushAsync();
}
return file;
}