One of the neat features that ParallelFX has is tasks, they are simply wrappers that allow you to easily start parallel operations. To create a task all you have to do is this:
Task task = Task.Create(n => LongRunningMethod(test));
The "n" parameter that you see is just the state that you can pass to the task. They provide an overload for you to pass this if you would want to, like this (oh and C# should have true optional parameters, I don’t care what Anders thinks, overloads are a messy solution </rant>):
Object state = new Object();
Task task = Task.Create(n => LongRunningMethod(test), state);
Tasks, once created, start running immediately assuming that a thread is available for it to run on. (ParallelFX defaults the number of threads to the number of processors on your box) You can hook up an event that will allow the Task to notify your application when it has finished or you can also check its "IsCompleted" property to wait for it to finish.
task.Completed += TaskCompleted;
while (!task.IsCompleted)
{
Thread.Sleep(1000);
}
So, what happens when you need to fire off a Task and then get a resulting value from the Task but you don’t know when the Task will finish? Well, this is when you use a Future. A Future (which surprisingly implements the Future pattern) is simply a Task that is wrapped with a result value property that waits for the Task to be completed.
Future<string> future =
Future.Create<string>(() => LongRunningMethod(test));
string result = future.Value;
In this code we will fire off a separate thread running "LongRunningMethod" and then I will get the value for it. If the thread is not done when I request the return value then the call to Value will wait for the thread to finish before continuing.
While playing with this code I realized that the Future class provided no overload for passing state into a Future. So I promptly went to the MSDN forums and asked if they were planning on implementing this. I did get a response and they said that they are certainly considering it. I sure hope so! That would make something like this possible:
string[] names = { "Richmond, VA", "Washington, DC", "Boston, MA",
"Los Angeles CA", "Las Vegas, NV", "Seattle, WA" };
List<string> results = new List<string>();
List<Future<string>> futures = new List<Future<string>>();
foreach (string name in names)
{
futures.Add(
Future.Create<string>(n => LongRunningMethod((string)n), name));
}
foreach (Future<string> future in futures)
{
results.Add(future.Value);
}
Of course you can also accomplish this task with Parallel Linq (another part of ParallelFX), but that is for another post! One last thing to add is that if you need to tell ParallelFX how many threads to use, you can accomplish it like this:
TaskManagerPolicy policy = new TaskManagerPolicy(0, 10);
TaskManager manager = new TaskManager(policy);
Future<string>.Create(() => LongRunningMethod("value"), manager);
That code would tell ParallelFX to use a minimum of 0 threads with an ideal thread count of 10.
Well, this post is pretty short, but Tasks and Futures really are that simple. Parallel programming has never been easier!
Loved the article? Hated it? Didn’t even read it?
We’d love to hear from you.