c# – 在本地存储Windows 8 Metro App中保存对象时拒绝访问

我正在尝试将List(Show是我的类实现IXmlSerializable)存储到本地隔离存储.我正在使用此页面中的代码:

http://metrostoragehelper.codeplex.com/

我已经实现了“问题”部分中建议的更改.

我从项目列表中单击时使用以下代码添加Show对象.

private async void addShowButton_Click_1(object sender, RoutedEventArgs e)
    {
        var isoStorage = new StorageHelper<List<Show>>(StorageType.Local);

        List<Show> currentShows = await isoStorage.LoadASync("myShowsEx");
        if(currentShows == null) {
            currentShows = new List<Show>();
        }

        currentShows.Add(currentShow);

        isoStorage.SaveASync(currentShows, "myShowsEx");


        //Read it back, for debugging to check if it has been added properly. 
        List<Show> currentShowsRB = await isoStorage.LoadASync("myShowsEx"); //Exception here

    }

第一个节目添加完全正确,它显示在currentShowsRB列表中.单击第二个项目并调用上述方法时,最后一次LoadAsync调用发生异常:拒绝访问. (HRESULT异常:0x80http://metrostoragehelper.codeplex.com/5(E_ACCESSDENIED))
如何绕过它来访问本地数据存储以进行多次调用?

以下是StorageHelper的相关代码:

public async void SaveASync(T Obj, string FileName)
    {

        FileName = FileName + ".xml";
        try
        {
            if (Obj != null)
            {
                StorageFile file = null;
                StorageFolder folder = GetFolder(storageType);
                file = await folder.CreateFileAsync(FileName, CreationCollisionOption.ReplaceExisting);

                using (var writeStream = await file.OpenAsync(FileAccessMode.ReadWrite))
                {
                    Stream outStream = Task.Run(() => writeStream.AsStreamForWrite()).Result;
                    serializer.Serialize(outStream, Obj);
                    //writeStream.Dispose(); //Added and we get UnauthorizedAccessException
                    // outStream.Dispose(); //Added ObjectDisposedException caught in catch statement below
                }
            }
        }
        catch (Exception)
        {
            throw;
        }
    }
    public async Task<T> LoadASync(string FileName)
    {
        FileName = FileName + ".xml";
        try
        {
            StorageFile file = null;
            StorageFolder folder = GetFolder(storageType);
            file = await folder.GetFileAsync(FileName);
            using (var readStream = await file.OpenAsync(FileAccessMode.Read))
            {
                Stream inStream = Task.Run(() => readStream.AsStreamForRead()).Result;
                inStream.Position = 0;
                return (T)serializer.Deserialize(inStream);
            }
        }
        catch (FileNotFoundException)
        {
            //file not existing is perfectly valid so simply return the default 
            return default(T);
            //throw;
        }
        catch (Exception)
        {
            //Unable to load contents of file
            throw;
        }
    }

我添加了writeStream.Dispose()行,但即使包含此行,我也会得到相同的Access拒绝错误消息.如果我还包含outStream.Dispose()行,那么我会在下面的catch语句中捕获一个ObjectDisposedException.还有什么我应该做的吗?

最佳答案 您不是在等待SaveAsync完成,尝试在Save仍在进行时加载.将其更改为:

//isoStorage.SaveASync(currentShows, "myShowsEx");
await isoStorage.SaveASync(currentShows, "myShowsEx");   

List<Show> currentShowsRB = await isoStorage.LoadASync("myShowsEx"); 

编辑,等待无效是一个标准问题.
快速解决方法是:

 await TaskEx.Run(() => isoStorage.SaveASync(currentShows, "myShowsEx"));

但您也可以在SaveASync()中移动TaskEx.Run().并且给出一个以Async结尾的名称,它不应该是无效的,但是:

Task SaveASyncT Obj, string FileName)
{ 
    return TaskEx.Run() => { .... }
}

我不相信Serialize的异步版本,因此它保留在TaskEx.Run().

点赞