我有一个类需要定期对其私有状态(ConcurrentDictionary)进行一些处理。我正在通过Task.Factory.StartNew(doStuff)
. 因为这个任务是修改集合,所以我想确保 doStuff 只在条件为真时执行一次。它所做的工作可以安全地忽略竞争条件,但我不希望冗余任务占用资源并尽可能挤出同步。现在我通过双重检查锁定来控制它,它工作正常,但是在方法的末尾添加非常冗长的代码:
public void method()
{
...
// do the method related stuff. Upon executing this method, the condition for
// executing the task could become true, so it is appropriate to try to start it,
// even though it is not directly related to the semantics of this method
...
// now see if the task should be run
if (clock.Now > timestamp.Plus(interval) && periodicTask == null)
{
lock (lockObject)
{
if (periodicTask == null)
periodicTask = Task.Factory.StartNew(this.DoStuff);
}
}
}
private void DoStuff()
{
doActualProcessing();
//signal that task is complete
timestamp = clock.Now;
periodicTask = null;
}
这种设置可以防止 DoStuff 被额外调用,但它看起来太冗长而且有点脏。理想情况下,我想封装这个单调用逻辑,这样我就可以做这样的事情:
public void method()
{
// do the method related stuff.
...
// now see if the task should be run
startTaskExactlyOnce(DoStuff);
}
我看到的唯一选择可能是Lazy<T>
用来完成此任务,但在这里似乎不合适,因为:1.我没有初始化对象,我正在运行任务 2.任务将定期运行,a每个周期单次 3. 我只需要启动任务,所以没有翻译用于Lazy<t>.Value
导致执行