假设我有一个需要使用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);
});
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢!
编辑:
由于我正在使用DI并且将注入此服务,因此将其作为"懒惰"资源使用或使用异步工厂对我来说不起作用(尽管在其他用例中它可能很好).因此,异步初始化应该封装在类中,并对IMyService消费者透明.
将初始化代码包装在"虚拟" AsyncLazy<>对象中的想法将完成这项工作,尽管对我来说感觉有点不自然.