从存储器读取XML文件WP8.1 StorageFile阿比 [英] Read xml file from storage with WP8.1 StorageFile Api

查看:138
本文介绍了从存储器读取XML文件WP8.1 StorageFile阿比的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序应该使用 StorageFile API 从存储器读取XML文件。这有许多工作要做异步因为他 StorageFile API 只提供了异步方法。

构造函数调用方法 CallAsyncMethod()这就要求和(应该)等待 LoadXmlFromStorageAsync 方法。

数据访问()构造函数不等待 CallAsyncMethod()并完​​成之前的XML文件加载。在 XMLDATA 变量时,我称之为 GetElement()方法,因此未初始化。这是因为构造函数不等待异步方法来完成。

我该如何解决这个问题?

我想我只是不明白异步/的await的事情。

数据访问类的使用

  VAR数据访问=新的DataAccess();
dataAccess.GetElement(测试); //的NullReferenceException

数据访问类

 公共密封类数据访问
{
    私人常量字符串文件名=data.xml中;
    私人常量字符串的文件路径= @MS-APPX:///数据/;
    私人的XDocument XMLDATA;    公开数据访问()
    {
        //需要包装此调用,async关键字不适用于construtor工作
        CallAsyncMethod();
    }    私人异步无效CallAsyncMethod()
    {
        等待LoadXmlFromStorageAsync();
    }    私人异步任务LoadXmlFromStorageAsync()
    {
        var文件=等待StorageFile.GetFileFromApplicationUriAsync(新的URI(string.Concat(文件路径,文件名)));        使用(VAR流=等待file.OpenStreamForReadAsync())
        {
            this.xmlData = XDocument.Load(流);
        }
    }    公共IEnumerable的<&的XElement GT; GetElement(字符串节点名称)
    {
        //因为的NullReferenceException XMLDATA尚未initializied
        返回this.xmlData.Descendants(节点名称).ToList();
    }
}


解决方案

从本质上讲,你不能这样做,你在做什么,除非你强行同步code。不过,我会建议另一种方法,你曾经等待 GetElement 被称为(如果它没有被称为previously)。当然,这不是一个线程安全的解决方案。

 公共密封类数据访问
{
    私人常量字符串文件名=data.xml中;
    私人常量字符串的文件路径= @MS-APPX:///数据/;
    私人的XDocument XMLDATA;    公开数据访问()
    {
    }    私人异步任务<&的XDocument GT; LoadXmlFromStorageAsync()
    {
        var文件=等待StorageFile.GetFileFromApplicationUriAsync(新的URI(string.Concat(文件路径,文件名)));        使用(VAR流=等待file.OpenStreamForReadAsync())
        {
            返回XDocument.Load(流);
        }
    }    公共异步任务<&IEnumerable的LT;的XElement>> GetElement(字符串节点名称)
    {
         如果(this.xmlData == NULL)
             this.xmlData =等待LoadXmlFromStorageAsync();         返回this.xmlData.Descendants(节点名称).ToList();
    }

}

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();
    }
}

解决方案

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();
    }

}

这篇关于从存储器读取XML文件WP8.1 StorageFile阿比的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆