C#异步对象初始化

时间:2014-11-10 10:42:14

标签: c# asynchronous

我正在编写Windows Phone 8.1应用程序,其中一个部分是LocalStorage访问权限。我编写的代码如下所示,但它有一些严重的问题。我需要使用异步方法初始化服务,不久之后,我正在使用其中一种方法(也是异步的)。

Service : IService
{
    private XmlFormatter xmlFormatter;

    public Service()
    {
        Initialize();
    }

    public async IList<Model> GetModelsAsync()
    {
        return xmlFormatter.GetModels();
    }

    private async void Initialize()
    {
        try
        {                
            StorageFile item = (StorageFile)await ApplicationData.Current.LocalFolder.GetItemAsync(this.settings.Get<string>(SettingNames.DataFilename));

            using (Stream readStream = await item.OpenStreamForReadAsync())
            {
                xmlFormatter = new XmlFormatter(XDocument.Load(readStream));
            }
        }
        catch (FileNotFoundException)
        {
            CreateFile();
            xmlFormatter = new XmlFormatter(null);
        }
        catch (Exception)
        {
            throw;
        }
    }
}

问题是GetModelsAsync方法在Initialize方法结束之前运行,因此xmlFormatter为null并且我收到NullReferenceException。我该如何同步这些方法?

2 个答案:

答案 0 :(得分:2)

永远不要在ctor中长时间运行进程,单独调用初始化。

答案 1 :(得分:1)

这有多种解决方案。我建议保存从Initialize方法返回的任务。在尝试使用xml格式化程序之前,我会在GetModelsAsync调用:await _initializeTask;

另一种解决方案是抛出一个异常,说明你的服务尚未初始化,但由于用户不是那个调用Initialize的用户,那只会是糟糕的设计。

第三种方法是将Initialize方法公开,并将责任放在用户上以调用它,并确保在调用类中的其他方法之前完成它。