【发布时间】:2019-11-18 09:58:09
【问题描述】:
我想做一件简单的事情(假设ContinueWith是thread-safe):
readonly Task _task = Task.CompletedTask;
// thread A: conditionally prolong the task
if(condition)
_task.ContinueWith(o => ...);
// thread B: await for everything
await _task;
问题:在上面的代码中await _task立即返回,忽略是否有inner任务。
_task 可以延长 多个 ContinueWith 的扩展要求,我将如何等待所有这些都完成?
当然我可以尝试用旧的线程安全方式来做:
Task _task = Task.CompletedTask;
readonly object _lock = new object();
// thread A
if(condition)
_lock(_lock)
_task = _task.ContinueWith(o => ...); // storing the latest inner task
// thread B
lock(_lock)
await _task;
或者通过将任务存储在线程安全集合中并使用Task.WaitAll。
但我很好奇第一个 sn-p 是否有简单的修复方法?
【问题讨论】:
-
您必须等待调用
ContinueWith()的任务返回,因此您必须执行_task = _task.ContinueWith(o => ...);之类的操作(您不需要添加顺便说一句,锁定分配引用 - 如果这就是你正在做的所有事情,那是一个原子操作。) -
您可以在
ContinueWith调用中指定TaskCreationOptions.AttachedToParent,以使父任务仅在子任务完成时完成。 -
您可能希望使用
TaskContinuationOptions.ExecuteSynchronously参数运行Continuation。 -
当分配给
_task时,您绝对确实需要一个锁,因为_task是从一个线程写入并从另一个线程读取的。否则,线程 B 可能会在线程 A 重新分配它之前读取_task字段的值,并且即使在线程 A 重新分配它之后也可能缓存该值。 -
如果可能,使用
await的方式更简洁:async Task Prolong() { if (condition) await ...; }然后_task = Prolong()和await _task。
标签: c# multithreading async-await task continuewith