考虑以下代码:
private Task _task;
private void M()
{
_task = Task.Factory.StartNew(() => {
// Do work
_task = null;
}, TaskCreationOptions.LongRunning);
}
我知道Task.Factory.StartNew
创建一个新的Task
并安排执行,然后返回Task
。我想知道上述逻辑是否有问题。是否有可能将Task.Factory.StartNew
的返回值分配给_task
,而不是执行传入的lambda?
或者StartNew
中是否有一些逻辑阻止了这个?
我当然可以设想在StartNew
内发生上下文切换,执行传入的lambda设置_task
到null
的情况,然后用非{覆盖它的返回值{1}} null
个实例。我在这个假设中是否正确?
答案 0 :(得分:1)
此代码 具有竞争条件。 StartNew
将安排运行,然后它将返回Task
,然后发生_task
的分配。因此,在分配_task
的返回值之前,任务的工作可能会或可能不会在其正文中达到StartNew
赋值,因此在运行该代码之后{{} 1}}可能是_task
或返回的任务,我们无从得知。
答案 1 :(得分:-1)
如果你不需要任务本身,而是想要一个“我忙”状态,那么以下模式可能会更合适
private bool _busy;
private void M()
{
if(_busy)
{
return;
}
_busy = true;
Task.Factory.StartNew(() => {
try
{
// Do work
}
finally
{
_busy = false;
}
}, TaskCreationOptions.LongRunning);
}
根据上下文和线程安全保证,您的代码使您必须采取更多措施......