Task.Factory.StartNew执行和返回值赋值顺序

时间:2017-08-24 15:22:08

标签: c# .net

考虑以下代码:

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设置_tasknull的情况,然后用非{覆盖它的返回值{1}} null个实例。我在这个假设中是否正确?

2 个答案:

答案 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);
}

根据上下文和线程安全保证,您的代码使您必须采取更多措施......

相关问题