Обеспечить однократный вызов асинхронного методаC#

Место общения программистов C#
Anonymous
Обеспечить однократный вызов асинхронного метода

Сообщение Anonymous »

Предположим, у меня есть класс, которому необходимо выполнить некоторую асинхронную инициализацию с использованием метода InitializeAsync().
Я хочу убедиться, что инициализация выполняется только один раз. Если другой поток вызывает этот метод во время инициализации, он будет «ожидать», пока не вернется первый вызов.

Я думал о следующей реализации (с использованием SemaphoreSlim ).
Есть ли лучший/более простой подход?

Код: Выделить всё

public class MyService : IMyService
{
private readonly SemaphoreSlim mSemaphore = new SemaphoreSlim(1, 1);
private bool mIsInitialized;

public async Task InitializeAsync()
{
if (!mIsInitialized)
{
await mSemaphore.WaitAsync();

if (!mIsInitialized)
{
await DoStuffOnlyOnceAsync();
mIsInitialized = true;
}

mSemaphore.Release();
}
}

private Task DoStuffOnlyOnceAsync()
{
return Task.Run(() =>
{
Thread.Sleep(10000);
});
}
}
Спасибо!

Изменить:
Поскольку я использую DI и этот сервис будет внедрен, использование его как «ленивого» ресурса или использование асинхронной фабрики для меня не сработает (хотя в других случаях это может быть полезно).
Таким образом, асинхронная инициализация должна быть инкапсулирована внутри класса и прозрачна для потребителей IMyService.

Идея обернуть код инициализации в «пустой» объект AsyncLazy выполнит эту работу, хотя мне он кажется немного неестественным.

Подробнее здесь: https://stackoverflow.com/questions/283 ... alled-once

Вернуться в «C#»