2012-10-24 66 views
0

我正在使用Windows 8 XAML/C#商店應用程序。我正嘗試在應用程序的生命週期中多次將Windows.Storage.ApplicationData.Current.LocalFolder中的XML加載到XDocument。但是,當我嘗試加載文件時,我收到System.UnauthorizedAccessException。這裏是我的方法:我從磁盤加載XML時得到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事件反覆出現,引發異常。沒有特定的情況。有時發生錯誤,有時不會發生。我哪裏錯了?我很新的asyncawait的東西。

+0

所以,如果你只是導航到文件夾,你可以讀取文件? – awright18

+0

你對該文件夾或文件的許可是什麼,並且你是否以管理員模式啓動VS? – Larry

+3

'Click'事件一個接一個地發生?也許可能是兩個'LoadXmlFromLocalFolderAsync'在同一時間執行,或者當另一個嘗試使用該文件時該文件被某個線程持有的事實。 –

回答

1

您可以檢查是否有真正的兩個線程試圖訪問該文件。查看異常的MessageStackTrace應該有所幫助。 類似

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

+0

我不認爲禁用按鈕方法正在工作。 (請參閱另一個答案的評論。)關於'try-catch-finally'塊:我應該把'catch'和'finally'放在什麼位置?如果我選擇顯示'抱歉,出錯了。'消息,會有太多的人。是否僅在開始時將XML加載到XDocument並定期寫入文件是一種好的做法?對不起,我真的很新鮮。 – akshay2000

+0

您使用'catch'以可視模式記錄錯誤或嘗試解決錯誤(如果可以的話)。無論發生什麼事,最後你都應該關閉文件。如果你經常寫這個文件,最好打開它並根據需要使用它,當你知道你不再需要它時關閉它。如果你很少使用它,最好每次打開它。 –

+0

我看到[this](http://goo.gl/k655z)人正在使用可綁定方法執行操作。這種方法是否有助於我的情況?我會試一試try-catch-finally。顯然,我需要重新構建我的應用程序! – akshay2000