3

这里表达了什么意图?:

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被另一个线程修改。

4

2 回答 2

7

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

不。

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

是的。

后者意味着这个锁即使没用也是善良的,对吧?

看起来是这样,尽管你不能总是在没有看到完整的上下文的情况下确定。例如,有时我会根据需要锁定的资源编写需要检查是否应该启动任务的代码,因此锁定刚刚启动任务的代码可能是合适的。但是,如果您除了开始任务之外什么都不做,那么情况可能并非如此。

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

这并不能防止这种情况发生。


旁注,修改该集合内的foreach集合是一个坏主意。一些集合会很好地抛出某种并发修改异常。不太好的集合只会产生损坏的结果。

于 2013-10-30T19:34:25.723 回答
2

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

在任务内部,您实际上应该锁定共享资源,而不是围绕任务的创建。除非任务非常快地完成并在退出锁之前被抢先调度,否则锁不会对资源的安全产生影响。

这是一个错误,是的。

于 2013-10-30T19:35:58.780 回答