Fei
Fei

Reputation: 495

C#.net 4 parallel programming

I'm reading a book called Pro .NET 4 Parallel Programming in C# by Adam Freeman. In Chapter 2 page 13 it talks about using Task<int> to return a result by using task1.Result to wait for it to finish. I don't understand why task2 has to wait for task1 to finish. They are on different threads.

It's something like below:

Task<int> task1 = new Task<int>(() => { ... ; return sum });
task1.Start();
Console.WriteLine("Result 1: {0}", task1.Result);

Task<int> task2 = new Task<int>(() => { ... ; return sum });
task2.Start();
Console.WriteLine("Result 2: {0}", task2.Result);

If I move to following line to the bottom it seems like task1 still executes first no matter how many times I tried.

Console.WriteLine("Result 1: {0}", task1.Result);

Why is this happening?

Upvotes: 2

Views: 545

Answers (5)

Govin
Govin

Reputation: 99

Task task1 = new Task(() => { ... ; return sum });
task1.Start();
Task task2 = new Task(() => { ... ; return sum });
task2.Start();
task1.Wait()
Console.WriteLine("Result 1: {0}", task1.Result);
task2.Wait()
Console.WriteLine("Result 2: {0}", task2.Result);

Try this. Here you need to start both the task before calling the console.writeline.

Upvotes: 0

Bengie
Bengie

Reputation: 1035

"Console.WriteLine("Result 1: {0}", task1.Result);" can't run until task1 finishes, so it waits/blocks.

While the tasks do run independent of each other, the calling thread calls the console.writeline in a sequential order. The results of those two tasks are forced to be in-order.

Upvotes: 0

Aimeast
Aimeast

Reputation: 1663

Try to use task.Wait() method.

        Task<int> task1 = new Task<int>(() => { int sum = 0; return sum; });
        task1.Start();
        task1.Wait();
        Console.WriteLine("Result 1: {0}", task1.Result);

        Task<int> task2 = new Task<int>(() => { int sum = Enumerable.Range(1, 10).Sum(); return sum; });
        task2.Start();
        task1.Wait();
        Console.WriteLine("Result 2: {0}", task2.Result);

Upvotes: 0

O. Jones
O. Jones

Reputation: 108641

The task that actually finishes first -- that is, hits its return statement first -- is, formally, unpredictable. They can finish their work before you accept their Results.

If the work your sample tasks do is not very large, it stands to reason that task1 will finish first even if you don't accept its Result (or in Java threading lingo, join it) first. That's because you Started it first.

Presumably you somehow know that task1 finished first. Is there a Console.WriteLine buried in the code for your tasks? If so, keep in mind that the Console subsystem serializes operations, so the first of your tasks to use it will do so completely before the second one can start. Think of it this way: your two tasks race to Console, and the winner takes all.

task1 has an unfair advantage in this race, because it's off and running before your main thread even starts constructing task2 with your second new.

Upvotes: 0

Nick Butler
Nick Butler

Reputation: 24383

Task.Result blocks until the Task completes.

It has to in order to have a result to return!

So, in your first example, task2 is not even started until task1 has completed.

If you move task1.Result to the bottom, it is indeterminate which task completes first, but your Console.WriteLine statements will execute in sequential order.

Upvotes: 3

Related Questions