C#异步对象初始化

本文关键字:初始化 对象 异步 | 更新日期: 2023-09-27 18:29:54

我正在编写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。如何同步这些方法?

C#异步对象初始化

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

另一种解决方案是抛出一个异常,表示您的服务尚未初始化,但由于用户不是调用Initialize的用户,这将是糟糕的设计。

第三种方法是公开Initialize方法,并让用户负责调用它,并确保它在调用类中的其他方法之前已经完成。

永远不要在ctor中执行长时间运行的进程,单独调用initialize。