Example task in C #

I am starting to use Tasks in C #. I am trying to execute this code.

private static void CreateSubtask() { Task<Int32[]> parent = Task.Run(() => { var results = new Int32[3]; new Task(() => results[0] = 0, TaskCreationOptions.AttachedToParent).Start(); new Task(() => results[1] = 1, TaskCreationOptions.AttachedToParent).Start(); new Task(() => results[2] = 2, TaskCreationOptions.AttachedToParent).Start(); return results; }); var finalTask = parent.ContinueWith( parentTask => { foreach (int i in parentTask.Result) Console.WriteLine(i); }); finalTask.Wait(); } 

FinalTask ​​only starts when the parent task completes, and the parent task ends when all three children are finished. You can use this to create fairly complex task hierarchies that go through all the steps you specify.

Instead, I got three lines:

0 0 0

I expected them to be

0 1 2

I'm right?

+7
c # parallel-processing
source share
3 answers

Using Task.Run with the parent task suppresses the AttachedToParent effect in the child task: http://blogs.msdn.com/b/pfxteam/archive/2011/10/24/10229468.aspx

Use Task.Factory.StartNew instead.

+6
source share

The problem is that your parent task finishes when it finishes running the other three tasks, and not when the other three tasks finish.

Instead, you can use Task.WhenAll to create a task that will be completed when all other tasks are completed.

Another change to make your program a more idiomatic task code is to make each internal task return its value, rather than mutate some general state, simply because dealing with the general state may be more difficult to reason in a multi-threaded environment.

 var parent = Task.WhenAll(Task.Run(() => 0), Task.Run(() => 1), Task.Run(() => 2)); var finalTask = parent.ContinueWith(t => { foreach (int n in t.Result) Console.WriteLine(n); }); finalTask.Wait(); 
+4
source share

You are just starting your three subtasks, but you are not waiting for their completion. Adapt it like this:

  var task1 = new Task(() => results[0] = 0, TaskCreationOptions.AttachedToParent); var task2 = new Task(() => results[1] = 1, TaskCreationOptions.AttachedToParent); var task3 = new Task(() => results[2] = 2, TaskCreationOptions.AttachedToParent); task1.Start(); task2.Start(); task3.Start(); task1.Wait(); task2.Wait(); task3.Wait(); 

Also note that with your current code you can still show 0 1 2 (not 1 2 3 way), since it is not detected when subtasks work / end. It may also depend on the configuration of the assembly (debug / release).

0
source share

All Articles