Предположим, что у меня есть класс с членами, для которых требуются асинхронные действия для инициализации (например, файлы ввода/вывода или веб-запросы). Мне нужно только инициализировать один раз, и я не хочу повторно инициализировать.Инициализировать Async Only Once Pattern
Задачи и Async-Await подходит для этого?
Вот пример того, что я сейчас делаю:
private Task _initializeTask;
public Task InitializeAsync()
{
return _initializeTask ?? (_initializeTask = Task.Run(
async() =>
{
// Do an action requiring await here
await _storageField.LoadAsync();
}));
}
ли это сделать то, что я думаю, что это делает? Есть ли лучшие способы сделать это?
Это поточный сейф? Это не требование, но его следует учитывать.
изменения:
То, что я думаю, что это делает? Я считаю, что если _initializeTask не был назначен, ему будет назначена новая задача, которая начнется, а затем ждет асинхронную лямбду, содержащуюся внутри. Любые последующие вызовы метода ждут уже запущенной (или завершенной) задачи, которая была назначена _initializedTask.
Когда я хочу его построить? Обычно я использую этот метод для службы, которую я разрешаю с контейнером IoC. Несколько зависимых классов могут быть построены со ссылкой на класс. Затем, перед использованием, каждый из них ожидает InitializeAsync(). Если theres несколько зависимых классов, то я не хочу удваивать его при инициализации.
Заводской метод? Обычно не нужно создавать несколько экземпляров, которые должны быть инициализированы, поэтому метод Factory не кажется хорошим решением. Я использовал что-то вроде статического метода CreateAsync() для таких вещей, как классы оболочки папок, но это не позволяло мне вводить инициализированные папки в конструкторы. Методы Async Factory ничего не получают, если они не могут использоваться с инъекцией конструктора IoC.
Что вы думаете, что делает? –
Вы хотите 'Lazy' для Lazy поведения загрузки. или статический конструктор для кода init, который является общим для всех экземпляров класса. –
Aron
Когда вы хотите * начать * инициализировать? О строительстве? –