在 Tasks 中使用 lock() 是否安全?

Is it safe to use lock() with Tasks?

我在这里阅读:

.NET async, can a single thread time-slice between tasks?

除非您显式使用 async/await,否则任务不会 "time-slice" 在后端线程池中的同一线程上。这有保证吗?或者仅仅是当前实施 TPL 的副作用?

如果不能保证,使用时会出现问题 lock():

考虑两个任务,它们在释放之前访问 locks 完整 SerialPort 事务(发送消息并接收,或超时)的方法。如果时间分片发生在同一个线程上并且 SerialPort 访问速度足够慢,lock 将无法完成它的工作(让两个调用通过,因为它们在技术上是在同一个线程上)。

是的,只要您不做任何使您的代码(的某些部分)在另一个线程上执行的操作(awaitTask.Run()Task.ContinueWith()Thread, …),那么使用 lock 或其他基于线程的同步机制是安全的。

一个可能的例外是,如果您有自定义 TaskScheduler(例如 TaskScheduler.FromCurrentSynchronizationContext())并且您以某种方式让该调度程序尝试执行更多 Task,而您的 Task仍在执行(例如 Application.DoEvents())。在这种情况下,您的 Task 仍然不会移动到另一个线程,但它可能会暂停,而另一个 Task 在同一线程上执行。不过这种情况应该是极其罕见的。