Welcome to MSDN Blogs Sign in | Join | Help

News

  • These postings are provided "AS IS" with no warranties and confer no rights. All code and tools presented are done so under the Microsoft Public License.
What’s new in Beta 1 for the Task Parallel Library? (Part 2/3)

Related Posts:

Last week we talked about changes under the covers, redesigns in System.Threading.Parallel, and using CancellationTokens.  So what else is new in TPL for Beta 1?  In this post, we’ll cover the new TaskFactory class, the plight of Future<T> (Task<TResult>), and TaskCompletionSource<TResult>.

TaskFactory

There are two ways to create and schedule Tasks: use constructors and instance methods, or use static methods like StartNew.  In previous releases, these two functionalities were jammed into the Task class, and we realized that separating them would result in a cleaner design.  So we introduced the TaskFactory class, which contains all static methods that create and/or schedule Tasks.  In Beta 1, these static methods include more than just StartNew, but those will be covered in the next post!

For convenience, Task now contains a static Factory property which returns a default instance of TaskFactory.  So for many users, the biggest practical difference is that where you would have used Task.StartNew (or Task.Create in the June 2008 CTP and earlier), you now use:

Task.Factory.StartNew(() =>

{

    ...
});

 

An additional advantage of TaskFactory is the ability to consolidate the specifying of options such as creation options, continuation options, and which scheduler to use: 

TaskFactory myFactory = new TaskFactory(

    myScheduler, myCreationOptions, myContinuationOptions);

 

Task t0 = myFactory.StartNew(() => { });

Task t1 = myFactory.StartNew(() => { });

Task t2 = myFactory.StartNew(() => { });

 

Task<TResult>

In previous releases, Tasks that produced results were called Futures.  Moving forward, we’ve opted to rename Future<T> to Task<TResult>, a type that derives from Task.  There were a number of reasons, including:

·         We constantly found ourselves describing Futures as “tasks that return results”.

·         Many folks, that we spoke with, found the name Task<TResult> clearer.

·         There is some discrepancy in literature and concurrency circles about exactly what’s implied by the term “future” (What functionality should or should not be exposed?  Side-effect free?)

·         The name Future has a not-related-to-Task implication.  However, we wanted Task<TResult> to derive from Task so that the former could be treated polymorphically as the latter.

·         We wanted TaskFactory methods to be able to return “tasks that return results”.  For example, it would have been odd for Task.Factory.StartNew to return a Future.

TaskCompletionSource<TResult>

A Task<TResult> is typically used to asynchronously execute a delegate that computes and returns a result.  Sometimes however, the asynchronous operation cannot be represented by a delegate, but rather is performed by an external entity.

Such functionality was originally supported on Future<T>, via a special constructor that did not take a delegate.  A Future created this way could have its Value or Exception properties set using the respective setters.  There were several problems with this approach, for example:

·         The setters were only usable if the Future<T> was created with the special constructor.

·         Commonly, a producer would want to hand out a Future<T> to consumers, but not allow the consumers to resolve it.  However, in this scheme, anyone who had a reference to the Future<T> could resolve it.

We’ve addressed these issues by introducing a new TaskCompletionSource<TResult> type: 

TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();

Task<int> task = tcs.Task;

 

// Sometime later...

tcs.SetResult(computedResult);  // Or tcs.SetException(exc), or tcs.SetCanceled()

 

// In a consumer elsewhere...

try { Console.WriteLine(task.Result); }

catch (AggregateException ae) { }

 

In this post, we covered the most fundamental redesigns to TPL tasks.  “What’s new in Beta 1 for TPL (Part 3/3)” will cover all remaining changes, such as other helper methods on TaskFactory and the new TaskScheduler.  Look forward to it!

Posted: Monday, April 06, 2009 9:23 PM by dashih

Comments

Pablo Marambio said:

About changing the name from Future<T> to Task<TResult>: Nice! seems clearer for me too :)

# April 7, 2009 10:30 AM

QuantumBitDesigns said:

Very nice on all points/changes

# April 7, 2009 12:51 PM

Jack said:

I just noticed the syntax, it is so cool

# April 7, 2009 11:13 PM

Parallel Programming with .NET said:

Related posts: What’s new in Beta 1 for the Task Parallel Library? (Part 1/3) What’s new in Beta 1 for

# April 14, 2009 5:34 PM

Parallel Programming with .NET said:

A number of improvements have been made to Parallel Extensions since the Visual Studio 2010 CTP across

# April 29, 2009 2:56 PM

Parallel Programming with .NET said:

We’re very excited that the .NET Framework 4 Beta is now available for public download, as .NET 4 has

# May 20, 2009 6:39 PM

Développement parallèle said:

Mots clés Technorati : Visual Studio 2010 , PFX , Concurrency Runtime , TPL , PLINQ , Exemples , Documentation

# May 21, 2009 6:21 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

  
Enter Code Here: Required

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Page view tracker