我的应用程序应使用StorageFile API
从存储中读取xml文件。这必须是异步的,因为StorageFile API
仅提供async
方法。
构造函数调用方法CallAsyncMethod()
,调用和(应该)等待LoadXmlFromStorageAsync
方法。
DataAccess()
构造函数不等待CallAsyncMethod()
并在加载XML文件之前完成。因此,当我调用xmlData
方法时,GetElement()
变量不会被初始化。这是因为构造函数不会等待异步方法完成。
我该如何解决这个问题?
我想我只是没有得到async / await的东西。
使用DataAccess类
var dataAccess = new DataAccess();
dataAccess.GetElement("test"); //NullReferenceException
DataAccess类
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();
}
}
答案 0 :(得分:4)
除非您强行同步代码,否则基本上您无法执行您正在执行的操作。但是,我会建议一种替代方法,等待GetElement
被调用(如果以前没有调用过)。当然,这不是一个线程安全的解决方案。
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();
}
}