【发布时间】:2015-02-05 09:18:50
【问题描述】:
假设我有一个类需要使用 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<> 对象中的想法可以完成这项工作,尽管我觉得这有点不自然。
【问题讨论】:
-
使用
Lazy,其初始化方法可以满足您的需求。这确保了初始化方法只被调用一次 -
如果您使用此解决方案,请务必在 finally 块中调用
Release。
标签: c# .net asynchronous async-await task-parallel-library