Bartosz Wójtowicz
Bartosz Wójtowicz

Reputation: 1401

Queue a task for execution when all currently scheduled tasks finish - no references to the tasks

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

Answers (1)

noseratio
noseratio

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

Related Questions