Read xml file from storage with WP8.1 StorageFile Api

你。 提交于 2019-12-11 19:03:41

问题


My application should read an xml file from storage using the StorageFile API. This has to be done async since he StorageFile API provides only async methods.

The Constructor calls the method CallAsyncMethod() which calls and (should) await the LoadXmlFromStorageAsync method.

The DataAccess() constructor does not wait for the CallAsyncMethod() and completes BEFORE the XML file is loaded. The xmlData variable is therefore not initialized when i call the GetElement() method. This is because the constructor does not wait for the async method to complete.

How can I fix this?

I guess i just don't get the async/await thing.

usage of DataAccess class

var dataAccess = new DataAccess();
dataAccess.GetElement("test"); //NullReferenceException

DataAccess class

public sealed class DataAccess
{
    private const string FileName = "data.xml";
    private const string FilePath = @"ms-appx:///Data/";
    private XDocument xmlData;

    public DataAccess()
    {
        //need to wrap this call, the async keyword does not work for construtor
        CallAsyncMethod();
    }

    private async void CallAsyncMethod()
    {
        await LoadXmlFromStorageAsync();
    }

    private async Task LoadXmlFromStorageAsync()
    {
        var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(string.Concat(FilePath, FileName)));

        using (var stream = await file.OpenStreamForReadAsync())
        {
            this.xmlData = XDocument.Load(stream);
        }
    }

    public IEnumerable<XElement> GetElement(string nodeName)
    {
        //NullReferenceException because xmlData is not initializied yet
        return this.xmlData.Descendants(nodeName).ToList();
    }
}

回答1:


Essentially you can't do what you're doing, unless you forcefully synchronize the code. However, I would recommend an alternative approach, where you await once GetElement is called (if it haven't been called previously). Of course, this is not a thread-safe solution.

public sealed class DataAccess
{
    private const string FileName = "data.xml";
    private const string FilePath = @"ms-appx:///Data/";
    private XDocument xmlData;

    public DataAccess()
    {
    }

    private async Task<XDocument> LoadXmlFromStorageAsync()
    {
        var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(string.Concat(FilePath, FileName)));

        using (var stream = await file.OpenStreamForReadAsync())
        {
            return XDocument.Load(stream);
        }
    }

    public async Task<IEnumerable<XElement>> GetElement(string nodeName)
    {
         if (this.xmlData == null)         
             this.xmlData = await LoadXmlFromStorageAsync();

         return this.xmlData.Descendants(nodeName).ToList();
    }

}



来源:https://stackoverflow.com/questions/23311287/read-xml-file-from-storage-with-wp8-1-storagefile-api

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!