用锁包装任务不是很有用

本文关键字:有用 任务 包装 | 更新日期: 2023-09-27 18:37:28

这里表达的意图是什么?

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

用锁包装任务不是很有用

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

不。

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

是的。

后者暗示这个锁即使无用也是善良的,对吧?

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

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

这无助于阻止这种情况。


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

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

在任务内部,您应该实际锁定共享资源,而不是围绕任务的创建。除非任务以极快的速度完成并在退出锁之前被抢占地安排,否则锁定不会影响资源的安全性。

这是一个错误,是的。