I'd like to know which (if any) is the most straightforward way of queuing work items (delegates) to the thread pool in .Net 4.5 using System.Threading.Task
objects. What I want to do essentially is to replicate the queuing functionality of the ThreadPool.QueueUserWorkItem()
method with Task
s. Please correct me if i'm wrong, but as far as I know the work items enqueued using this method are guaranteed to be executed in the order they were enqueued (maybe I'm completely wrong for multi-processor scenarios). I have to write code that behaves the same, using Task
s.
I am working on a portable class library, so that's why I can't use ThreadPool.QueueUserWorkItem()
, but instead I have to rely on Task
s for this objective. What technique would you suggest? Is the default task scheduler suitable for this requirement?
What you ask is exactly what Tasks do already. A Task is essentially a wrapper around a lambda that by default gets queued to execute on the ThreadPool. On top of that, Tasks add continuations, exception handling, cancellation and many convenience functions that make multi-threading a lot easier.
If you don't want to use the ThreadPool, you can create your own TaskScheduler and use it when creating a new Task. A TaskScheduler essentially receives a Task and schedules it for execution.
The default TaskScheduler uses ThreadPool.QueueUserWorkItem plus some work-stealing magic and multiple queue handling. Other implementations can use a priority queue, set their own limits on the maximum or minimum number of threads or whatever technique their author wants to use.
EDIT
I didn't notice the Portable part from the beginning. So the question is "Does the PCL provide a TaskScheduler that uses the ThreadPool or do I have to create my own"?
.NET 4+ provides the ThreadPoolTaskScheduler. Unfortunately, this seems to be missing from the PCL subset. It looks that you may have to create your own TaskScheduler or use a Nuget Package to add platform specific implementations.
Somehow, I think that ThreadPoolTaskScheduler would be a bad choice for a Windows Phone project
After some diggind using Resharper and .NET's debug symbols, I think the PCL finds any available platform TaskScheduler implementations by itself.
In .NET 4.0, TaskScheduler.Default returns an instance of ThreadPoolTaskScheduler, an interal BCL class. In the PCL subset, TaskScheduler.Default returns null and ThreadPoolTaskScheduler is not available.
The source code for ThreadPoolTaskScheduler is probalby available from Microsoft's Reference Source Servers, but you can also browse it quickly at dotnetframework.org
I created a PCL class that returns a new task and called it from a .NET 4.5 console application to see what TaskScheduler it would use. I found that the PCL class actually used the ThreadPoolTaskScheduler.
I haven't tried this with a Windows 8 or Windows Phone 8 project yet, although I suspect I'll get each platform's default TaskScheduler.