2014-11-10 2 views
0

Я пишу приложение Windows Phone 8.1, а его часть - LocalStorage. Я написал код, как показано ниже, но у него есть серьезная проблема. Мне нужно инициализировать сервис, используя асинхронные методы, и некоторое время после этого, я использую один из его методов (который также является асинхронным).Инициализация объекта async C#

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 является недействительным и я получаю NullReferenceException. Как синхронизировать эти методы?

ответ

1

Существует несколько решений. Я бы предложил сохранить задачу, которая возвращается из метода Initialize. Затем я попросил бы в GetModelsAsync позвонить: await _initializeTask;, прежде чем пытаться использовать форматировщик xml.

Другим решением является исключение, в котором говорится, что ваша служба еще не инициализирована, но поскольку пользователь не является инициатором инициализации, это будет просто плохим дизайном.

В-третьих, сделать метод Initialize общедоступным и возложить на пользователя ответственность за его вызов и убедиться, что он был закончен, прежде чем ссылаться на другие методы в вашем классе.

+0

Итак, вы предлагаете мне (вариант 1) написать 'await _initializeTask;' сразу после открытия скобки? – Fka

+0

Я даю вам три разных решения, это зависит от вас, чтобы выбрать один. Если вы хотите использовать первое решение, я бы поставил ожидающий вызов прямо перед тем, как попытаться получить доступ к форматированию xml. – Cybrosys

+0

Спасибо за совет :) – Fka

2

Никогда не выполняйте длительные процессы в ctor, вызывайте инициализацию отдельно.

Смежные вопросы