【问题标题】:Queue a task for execution when all currently scheduled tasks finish - no references to the tasks当所有当前计划的任务完成时排队执行任务 - 不引用任务
【发布时间】:2014-07-04 09:11:01
【问题描述】:

当所有当前计划的任务都完成后,是否可以排队执行新任务?我不能使用TaskFactory.ContinueWhenAll,因为我没有对计划任务的引用,因为它们是由子组件计划的。获取所有当前计划的任务会有所帮助,因为在这种情况下,我可以使用 ContinueWhenAll 方法来使用它们。

【问题讨论】:

  • 您可以实现自己的 TaskScheduler,它是实际 TaskScheduler 的包装器。
  • 我不明白如何做到这一点,因为 GetScheduledTasks() 是一种受保护的方法。
  • 只需拥有自己的TaskScheduler,它将每个排队的任务存储在一个列表中,然后再将其传递给“真正的”TaskScheduler
  • 只要他们不专门使用TaskScheduler.Default,是的。看到这个答案:stackoverflow.com/a/21968669/885318
  • 您无法控制进程中正在运行的任务。任何库,包括 BCL,都可以启动任务。等待所有任务是非常危险和不稳定的。

标签: c# multithreading task-parallel-library task


【解决方案1】:

是否可以在当前所有任务都排队执行新任务 计划任务完成了吗?

我认为没有通用的方法可以做到这一点,除非您想使用反射技巧(这将不可避免地使您受限于当前的 TPL 实施细节)。

假设,您可以实现自定义TaskScheduler 并将其传递给Task.Factory.StartNewTask.ContinueWithTask.Start。您仍然无法控制其他人创建的任务,这些任务明确使用 TaskScheduler.DefaultTaskScheduler.FromSynchronizationContext()

此外,可能还有由async 方法创建的任务,如下所示:

async Task DoAsync() { await Task.Delay(1); }

它们的创建根本没有任务调度程序(在TaskScheduler 意义上)。您可以实现自定义同步上下文并跟踪使用SynchronizationContext.Post 发布的项目。然而,并非所有这些项目都必然代表任务延续。此外,您将无法跟踪像 await task.ConfigureAwait(false) 这样的延续。

这可能表明您需要重新设计您的任务工作流逻辑或与其他开发人员协调。假设您可以访问一些您想要使用TaskFactory.ContinueWhenAll 跟踪的根父任务.那些父任务以即发即弃的方式创建一些子任务然后完成,而子任务对您不可用。这是错误的:在所有子任务完成之前,父任务应该正常完成。至少有几种方法可以解决此问题,例如使用 async/awaitTask.Unwrap,前提是可以更改第 3 方代码。

【讨论】:

  • 在没有其他答案的情况下,我得出结论,没有办法按照你说的那样正确地做到这一点。在这种情况下,我接受你的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-25
相关资源
最近更新 更多