2012-09-13 83 views
1

Preconditions: Windows 8 Pro RTM + VS2012 Ultimate RTM为什么这段代码会在win8 rtm中引发异常,但不会在win8 rp中引发异常?

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(); 
     ....... 
    } 

.3。 会发生什么:第一次启动应用程序时,下面的代码抛出一个错误:

var ReadStream1 = await file1.OpenStreamForReadAsync() as Stream; 

Error: UnauthorizedAccessException was unhandled by user code Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

I check the folder, the xml file is created when the error happen. 

0.4。 更多内容:当我重新打开应用程序时,没有任何反应,它像一个魅力。我不知道为什么,该应用程序在Win8 RP和VS 2012 RC中运行良好。我改变什么,但为什么不能在Win8中RTM与VC2012运行RTM

+1

它看起来像你对我试图打开文件时仍然被在不同的线程生成它。 – yms

回答

1

因为你的第二个代码块使用一个变量名xmlfilename如果事实上你试图打开相同的文件,我不知道,但我猜你是。由于在App.xaml.cs中创建文件的操作以及在MainPage.xaml.cs中读取文件的操作都是异步的,因此它们可能同时发生。解决这个问题的最简单方法是创建一个表示创建XML文件的应用程序级别的Task变量。像这样:现在

Task creatingFile = CheckXML(); 
createFile.Start(); 

,在MainPage.xaml中的文件,你可以检查,看看是否任务仍在使用运行creatingFile.IsCompleted(或IsFaulted)。如果任务完成,那么你可以打开文件。如果任务尚未完成,则可以使用creatingFile.ContinueWith(...)安排文件在创建后打开。

此外,不要忘记在使用语句中包装文件,以确保在完成使用时它们已关闭。像这样:

using (var ReadStream1 = await file1.OpenStreamForReadAsync() as Stream) 
{ 
... 
} 
+0

非常感谢。最终完成! –

1

Jared对此是正确的,但我不太喜欢应用程序范围内的任务参考。发生这种情况的原因是因为您无法等待返回void的方法。您已将方法CheckXMLCreateXML标记为async 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; 
} 
相关问题