我正在使用Windows 8 XAML / C#商店应用。我想在应用的生命周期内多次将Windows.Storage.ApplicationData.Current.LocalFolder
的XML加载到XDocument
。但是,当我尝试加载文件时收到System.UnauthorizedAccessException
。以下是我的方法:
添加到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);
}
仅用于调试目的:
private async void Button_Click_2(object sender, RoutedEventArgs e)
{
XDocument TempXDoc = await LoadXmlFromLocalFolderAsync("Categories.xml");
Debug.WriteLine(TempXDoc);
}
加载和保存方法:
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();
}
如果我重复触发Click
个事件,则抛出异常。没有特定的场景。有时会发生错误,有时则不会。我哪里错了?我对async
和await
这些东西很新。
答案 0 :(得分:1)
您可以检查真正有两个线程是否正在尝试访问该文件。查看异常的Message
和StackTrace
会有所帮助。
像
Message=Invalid cross-thread access.
StackTrace:
at MS.Internal.XcpImports.CheckThread()
应该出现在那里。
此问题的解决方案是使用LoadXmlFromLocalFolderAsync
方法的锁,这样两个线程无法同时打开文件。
http://msdn.microsoft.com/en-us/library/a8544e2s(v=vs.100).aspx
另外一个很好的建议是始终管理try-catch-finally
块中的文件。
但这有点脏。交互式应用程序中的问题不是允许用户像疯了一样快速点击按钮。您应该禁用按钮功能,直到当前完成。想象一下,按钮点击会发生更复杂的操作;这使得不必使用系统资源。不行。 您应该尝试使用阻止双击的方法,如下所示: http://tgynther.blogspot.ro/2011/07/aspnet-prevent-button-double-click.html