1

前提条件: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(); 
        .......
     }

.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.

.4。さらに何か:アプリを再度開いても何も起こらず、魅力のように機能します。理由はわかりませんが、このアプリはWin8RPとVS2012RCでうまく機能します。私は何も変更しませんが、VC2012RTMを使用してWin8RTMで実行できないのはなぜですか

4

2 に答える 2

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;
}
于 2012-09-13T23:46:47.093 に答える
1

2番目のコードブロックは変数名xmlfilenameを使用しているので、実際に同じファイルを開こうとしているかどうかはわかりませんが、そうだと思います。App.xaml.csでファイルを作成する操作と、MainPage.xaml.csでファイルを読み取る操作はどちらも非同期であるため、これらはおそらく同時に発生しています。これを解決する最も簡単な方法は、XMLファイルの作成を表すアプリケーションレベルのタスク変数を用意することです。そのようです:

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

これで、MainPage.xamlファイルで、createingFile.IsCompleted またはIsFaulted)を使用して、タスクがまだ実行されているかどうかを確認できます。タスクが完了したら、ファイルを開くことができます。タスクがまだ完了していない場合は、createingFile.ContinueWith(...)を使用して、作成後にファイルを開くようにスケジュールできます。

また、usingステートメントでファイルをラップして、使用が終了したときにファイルが閉じていることを確認することを忘れないでください。このような:

using (var ReadStream1 = await file1.OpenStreamForReadAsync() as Stream)
{
...
}
于 2012-09-13T19:16:49.510 に答える