PersonalNexus
PersonalNexus

Reputation: 1302

How can I schedule another task in .NET while the current one is blocking?

For my .NET 4.0 project, I am using a custom TaskScheduler with a limited degree of concurrency (similar to the LimitedConcurrencyLevelTaskScheduler example on MSDN). A bunch of the tasks it executes block while waiting for some other operation to return a result and then continue with their work. Because it is a shame that the threads of this scheduler don't have anything to do during this period of time, I would like to schedule another task while one blocks.

I thought that maybe the TPL could see when a task blocked and then schedule something else, but my experiments with Monitor.Wait() or waiting on a ManualResetEvent have shown that this is not the case. Since I am already using my own task scheduler I thought there might be way to tell it explicitly to schedule another task, but I haven't found any method on Task, TaskScheduler etc. to do so.

Note that continuations won't work here, as I am in the middle of one task executing. Also, I would really like to avoid splitting the tasks into two, a pre-wait and a post-wait task, because there are potentially several points where waiting is required and splitting them all would lead to a level of fragmentation of my original algorithm that would make it hard to maintain. I suppose things like await from the Async CTP would be helpful, but I have to stick with .NET 4 for this one.

Is there something I am missing to tell a task scheduler to dequeue the next task and then come back to the current one when that one done?

Upvotes: 2

Views: 458

Answers (3)

svick
svick

Reputation: 244757

If you have your own TaskScheduler, TPL doesn't schedule anything, that's the work of the TaskScheduler.

If you want some way to tell your custom TaskScheduler to schedule another Task, you will have to add it to your TaskScheduler by yourself. And you can't execute new Task and then “come back” to the old one, because there is no way to pause an executing Task.

But the simplest solution might be using the default TaskScheduler, since it takes blocked Tasks into account when deciding how many Tasks to schedule.

Upvotes: 2

usr
usr

Reputation: 171178

There is no such thing built-in. To avoid problems like this one, use non-blocking tasks.

You could also slightly oversubscribe the CPU by makign your own custom TaskScheduler run more threads in parallel than there are CPUs. This will lead to light inefficiencies but in case a task blocks, you have other "backfill" task already running and taking over the CPU.

Upvotes: 0

Prabhu Murthy
Prabhu Murthy

Reputation: 9261

Task.ContinueWith does gives you the option to schedule a task once your initial task is complete or faulted.but this helps only when the initial task has ran to completion.

Upvotes: 0

Related Questions