我目前有一个单例,初始化最多可能需要10秒.但是,我不希望我的用户对此初始化进行惩罚(等待),因此我宁愿在应用程序启动期间在后台线程上引导此组件.这就是我所拥有的:
辛格尔顿:
@H_403_4@public class MySingleton { private static MySingleton _instance; private static readonly object _locker = new object(); private MySingleton() { Init(); } public static MySingleton Instance { if(_instance == null) _instance = new MySingleton(); return _instance; } public void Init() { lock(_locker) { if(_instance != null) return; // long running code here... } } }应用程序启动:
@H_403_4@Task.Factory.StartNew(() => MySingleton.Instance.Init());这段代码可以正常工作,防止双初始化,在初始化之前防范用户需要它的边缘情况,并防止有人忘记调用Init().
然而,由于两个原因,它感觉有点笨重:
a)我将在启动时两次进入Init方法.
b)我想在单例内部进行线程化,但必须启动初始化.
是否有更清洁/更好/更好的方法来处理这个?
在此先感谢大家的帮助.
**编辑:正如评论中指出的那样,Init被误认为是私有的.它应该是公开的并且已得到纠正.
解决方法
使用静态构造函数来触发它,并使用ManualResetEvent进行同步.它为您提供了在实际课程中完成所有工作的解决方案.因此,它不依赖于某人应该调用您的init方法.
@H_403_4@public class MySingleton
{
private static MySingleton _instance;
private static ManualResetEvent _initEvent = new ManualResetEvent(false);
static MySingleton()
{
ThreadPool.QueueUserWorkItem(state => Init());
}
public static MySingleton Instance
{
_initEvent.Wait();
return _instance;
}
private static void Init()
{
_instance = new MySingleton();
// long running code here...
_initEvent.Set();
}
}