I get System.UnauthorizedAccessException while loa

2019-03-06 12:02发布

I am working on Windows 8 XAML/C# store app. I am trying to load XML from Windows.Storage.ApplicationData.Current.LocalFolder to XDocument multiple times during the lifetime of the app. However, I receive System.UnauthorizedAccessException when I try to load the file. Here are my methods:

To add to XML:

private async void AddCategoryButton_Click(object sender, RoutedEventArgs e)
{
    XDocument CategoryListXDoc = await LoadXmlFromLocalFolderAsync("Categories.xml");
    CategoryListXDoc.Element("CategoryList").Add(
        new XElement("Category", new XAttribute("Id", Guid.NewGuid()), AddCategoryTextBox.Text));
    SaveXDocToLocalFolderAsync("Categories.xml", CategoryListXDoc);
}

Just for debugging purposes:

private async void Button_Click_2(object sender, RoutedEventArgs e)
{
    XDocument TempXDoc = await LoadXmlFromLocalFolderAsync("Categories.xml");
    Debug.WriteLine(TempXDoc);
}

Load and Save methods:

private async Task<XDocument> LoadXmlFromLocalFolderAsync(string FileName)
{
    var LocalFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
    StorageFile CategoryListFile = await LocalFolder.GetFileAsync(FileName);
    var stream = await CategoryListFile.OpenStreamForReadAsync() as Stream;
    XDocument TempXDoc = XDocument.Load(stream);
    stream.Flush();
    return TempXDoc;            
}
private async void SaveXDocToLocalFolderAsync(string Filename, XDocument XDocToSave)
{
    var LocalFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
    StorageFile CategoryListFile = await LocalFolder.CreateFileAsync(Filename, CreationCollisionOption.ReplaceExisting);
    var stream = await CategoryListFile.OpenStreamForWriteAsync() as Stream;
    XDocToSave.Save(stream);
    stream.Flush();
}

If I fire the Click events repeatedly, the exception is thrown. There's no specific scenario. Sometimes error occurs, sometimes it doesn't. Where am I going wrong? I'm pretty new with the async and await stuff.

1条回答
一纸荒年 Trace。
2楼-- · 2019-03-06 12:29

You can check if truly two threads are trying to access that file. Viewing the Message and the StackTrace of the exception should help. Things like

  Message=Invalid cross-thread access.
 StackTrace:
   at MS.Internal.XcpImports.CheckThread()

should appears there.

A solution to this problem would be to use locks for the LoadXmlFromLocalFolderAsync method, in such way two threads could not open the file in the same time. http://msdn.microsoft.com/en-us/library/a8544e2s(v=vs.100).aspx Also a good suggestion for you is to always manage files in try-catch-finally blocks.

But this is getting a little dirty. The problem in interactive applications is not to allow users to click quickly buttons like crazy. You should disable button functionalities until the current one is finished. Imagine more complex operations occur at button click; this makes the system resources to be used unnecessary. It is not ok. You should try to use methods that prevent double clicking like this: http://tgynther.blogspot.ro/2011/07/aspnet-prevent-button-double-click.html

查看更多
登录 后发表回答