Reputation: 1401
Is it possible to queue a new task for execution when all currently scheduled tasks have finished? I cannot use TaskFactory.ContinueWhenAll because I don't have references to the scheduled tasks as they are scheduled by subcomponents. Getting all currently scheduled tasks would help as in that case I could use the ContinueWhenAll method using them.
Upvotes: 3
Views: 949
Reputation: 61666
Is it possible to queue a new task for execution when all currently scheduled tasks have finished?
I don't think there's a universal way of doing this, unless you want to resort to reflection hacks (which would inevitably bind you to the current TPL implementation details).
Say, you could implement a custom TaskScheduler
and pass it to Task.Factory.StartNew
, Task.ContinueWith
or Task.Start
. You'd still be unable to control the tasks created by others, which explicitly use TaskScheduler.Default
or TaskScheduler.FromSynchronizationContext()
.
Besides, there may be tasks out there created by async
methods, like this:
async Task DoAsync() { await Task.Delay(1); }
They are created without a task scheduler at all (in TaskScheduler
sense). You could implement a custom synchronization context and track items posted with SynchronizationContext.Post
. However not all of those items would necessarily represent task continuations. Morever, you won't be able to track continuations like await task.ConfigureAwait(false)
.
What may be a sign that you need to redesign your task workflow logic or coordinate it with other developers. Say, you have access to some root parent tasks which you want to track with TaskFactory.ContinueWhenAll
. Those parent tasks create some child tasks in fire-and-forget manner and then complete, and the child tasks are unavailable to you. This would be wrong: the parent tasks should not normally complete until all child tasks have completed. There are at least several ways of fixing this, like using async/await
or Task.Unwrap
, provided the 3rd party code can be changed.
Upvotes: 3