Я хочу убедиться, что инициализация выполняется только один раз. Если другой поток вызывает этот метод во время инициализации, он будет «ожидать», пока не вернется первый вызов.
Я думал о следующей реализации (с использованием 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