BT

New Task Parallel Library Features in .NET 4.6

| by Jonathan Allen Follow 638 Followers on Feb 09, 2015. Estimated reading time: 1 minute |

.NET’s Task Parallel Library is seeing a tune-up in the soon to be released .NET 4.6. In addition to some helper methods that reduce code, and possibly memory usage, TPL is gaining a solution to a tricky problem with SetResult.

On the boilerplate side, consider Task.FromResult. This function is used to create a Task that is already completed without having to first create a TaskCompletionSource. Developers can’t simulate this efficiency because it requires access to the internals of the Task type, which is a problem if you want to have the same effect using exceptions.

.NET 4.6 addresses this with the Task.FromException method. Like FromResult, it bypasses the TaskCompletionSource mechanism and its associated cost.

A related feature is the Task.CompletedTask property. This returns a completed Task object, which in the past would have been done by writing Task.FromResult<object>(null). Strictly speaking this isn’t necessary, but it does make the developer’s intentions a bit more clear.

All of these features are minor efficiencies compared to what the final feature in our list offers. A little known behavior of TaskCompletionSource.SetResult is that any continuations hanging off the associated Task object are potentially run synchronously. Stephen Toub explains why this is a problem,

I talked about a ramification of calling {Try}Set* methods on TaskCompletionSource<TResult>, that any synchronous continuations off of the TaskCompletionSource<TResult>’s Task could run synchronously as part of the call. If we were to invoke SetResult here while holding the lock, then synchronous continuations off of that Task would be run while holding the lock, and that could lead to very real problems. So, while holding the lock we grab the TaskCompletionSource<bool> to be completed, but we don’t complete it yet, delaying doing so until the lock has been released.

To avoid this problem, one can use this new RunContinuationsAsynchronously flag when creating the TaskCompletionSource:

tcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously)

.NET 4.6 is expected to be released along with Visual Studio 2015.

Rate this Article

Adoption Stage
Style

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Task.CompletedTask by Stephen Cleary

I think there's a real use case for Task.CompletedTask. If an interface defines a task-returning API but the implementation is synchronous, then the implementation should return a completed task. Today this is done with Task.FromResult, but that does create a new task instance each time it is called. In situations where this happens a lot, Task.CompleteTask would reduce memory pressure as well as make the intent clearer.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

1 Discuss
BT