codingjoe
codingjoe

Reputation: 810

Understanding System.Threading.Tasks behavior

I am currently trying to do some performance optimization by using Tasks to take advantage of parallel threading in .Net 4.0.

I have made three methods that returns collections of some objects or just an object. Lets call them MethodA, MethodB and MethodC.

Inside of MethodB I have a long-running delay - approximately 5-7 sec.

var person = new Person();

person.A = Task.Factory.StartNew(() => Mystatic.MethodA()).Result;
person.B = Task.Factory.StartNew(() => Mystatic.MethodB()).Result;
person.C = Task.Factory.StartNew(() => Mystatic.MethodC()).Result;

Now I am expecting person.A and person.C properties to be set / populated before person.B, but I have difficulties testing / debugging it to verify my assumptions.

I have added a parallel watch on all three properties, but debugging through is not clarifying things for me.

Also is this the proper way for me to optimize multiple calls to methods, if I am populating a main object?

In my case I have 5-7 different methods to gather data from, and I would like to make them parallel as some of them are relatively time-consuming.

Upvotes: 0

Views: 299

Answers (2)

YK1
YK1

Reputation: 7612

Your assumption is wrong. The Result property of Task will effectively wait for the task to complete - so, A, B , C will be assigned in that sequence. Also, this will defeat the purpose of creating async tasks.

One way is you can use Task.WaitAll on all three tasks and then assign the result from each task to A,B,C

you can also use async/await if you have VS2012 - you can still target .NET 4.0 by using http://nuget.org/packages/Microsoft.Bcl.Async/

However understand that async/await will not start 3 tasks in parallel if you do this:

person.A = await Task.Run(() => Mystatic.MethodA());
person.B = await Task.Run(() => Mystatic.MethodB());
person.C = await Task.Run(() => Mystatic.MethodC());

it will still be sequential - if you want parallel execution to some degree you can do this:

Task tA = Task.Run(() => Mystatic.MethodA());
Task tB = Task.Run(() => Mystatic.MethodB());
Task tC = Task.Run(() => Mystatic.MethodC());

person.A = await tA;
person.B = await tB;
person.C = await tC;   

Upvotes: 1

usr
usr

Reputation: 171178

Relying on timing is buggy by principle because timings are never guaranteed, especially not under real word conditions. You should apply proper waiting on tasks if you need to ensure that they have completed. Or use C# 5.0 async-await, or continuations.

In short, don't program by coincidence. Make your programs correct by construction.

Upvotes: 4

Related Questions