用lock包装一个Task不是很有用吗?

时间:2013-10-30 19:31:59

标签: c# multithreading task-parallel-library

这里表达了什么意图?:

lock(Locker)
{
    Task.Factory.StartNew(()=>
    {
        foreach(var item in this.MyNonCurrentCollection)
        {
          //modify non-concurrent collection
        }
    }, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchonizationContext())
    .ContinueWith(t => this.RaisePropertyChanged("MyNonCurrentCollection"));
}

系统lock(队列)会在Task完成之前还是系统只锁定以启动新的Task?后者意味着如果无用,这种锁是好的,对吧?我只是想从别人的代码中发现意图。这里的理想是保护MyNonCurrentCollection不被另一个线程修改。

2 个答案:

答案 0 :(得分:7)

  

系统是否会锁定(队列),直到任务完成

没有

  

系统只会锁定以启动新任务吗?

  

后者意味着这种锁是无用的,对吧?

看起来似乎如此,虽然你不能总是确定没有看到完整的背景。例如,有时我会根据需要锁定的资源编写需要检查是否应该启动任务的代码,因此锁定只是启动任务的代码可能是合适的。如果除了开始任务之外你没有做任何事情,那可能不是这样的。

  

这里的理想是保护MyNonCurrentCollection不被另一个线程修改。

这无法阻止这种情况。


旁注,在foreach内修改该集合的集合是一个坏主意。一些集合将足够好,只是抛出某种并发修改异常。不太好的收藏只会产生错误的结果。

答案 1 :(得分:2)

系统将锁定,直到任务被实例化并启动。 Task.Factory.StartNew是异步的。即使任务需要一段时间,也不应该长时间获取锁定。

在任务内部,您应该实际锁定共享资源,而不是创建任务。锁定不会影响资源的安全性,除非任务完成得非常快,并在退出锁定之前先进行预先安排。

这是一个错误,是的。