Skip to content

Commit ac8d311

Browse files
committed
review
1 parent bb6aa4b commit ac8d311

File tree

22 files changed

+386
-223
lines changed
  • LISTING 1-1 Parallel Invoke/LISTING 1-1 Parallel Invoke
  • LISTING 1-10 Exceptions in PLINQ/LISTING 1-10 Exceptions in PLINQ
  • LISTING 1-11 Create a task/LISTING 1-11 Create a task
  • LISTING 1-12 Run a task/LISTING 1-12 Run a task
  • LISTING 1-13 Task Factory/LISTING 1-13 Task Factory
  • LISTING 1-13 Task returning a value/LISTING 1-13 Task returning a value
  • LISTING 1-14 Task waitall/LISTING 1-14 Task waitall
  • LISTING 1-15 Continuation tasks/LISTING 1-15 Continuation tasks
  • LISTING 1-16 Continuation options/LISTING 1-16 Continuation options
  • LISTING 1-17 Attached child tasks/LISTING 1-17 Attached child tasks
  • LISTING 1-18 Creating threads/LISTING 1-18 Creating threads
  • LISTING 1-19 Using ThreadStart/LISTING 1-19 Using ThreadStart
  • LISTING 1-20 Threads and lambda expressions/LISTING 1-20 Threads and lambda expressions
  • LISTING 1-21 ParameterizedThreadStart/LISTING 1-21 ParameterizedThreadStart
  • LISTING 1-22 thread lambda parameters/LISTING 1-22 thread lambda parameters
  • LISTING 1-23 aborting a thread/LISTING 1-23 aborting a thread
  • LISTING 1-24 shared flag variable/LISTING 1-24 shared flag variable
  • LISTING 1-25 Using join/LISTING 1-25 Using join
  • LISTING 1-26 ThreadLocal/LISTING 1-26 ThreadLocal
  • LISTING 1-27 Thread context/LISTING 1-27 Thread context
  • LISTING 1-28 Thread pool/LISTING 1-28 Thread pool
  • LISTING 1-2 ParallelForEach in use/LISTING 1-2 ParallelForEach in use

22 files changed

+386
-223
lines changed

LISTING 1-1 Parallel Invoke/LISTING 1-1 Parallel Invoke/Program.cs

+20-12
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,40 @@ class Program
88
{
99
static void Task1()
1010
{
11-
Console.WriteLine("Task 1 starting");
11+
Console.WriteLine("Task 1 starting.");
1212
Thread.Sleep(2000);
1313
//Thread.Sleep(1000);
14-
Console.WriteLine("Task 1 ending");
14+
Console.WriteLine("Task 1 ending.");
1515
}
1616

1717
static void Task2()
1818
{
19-
Console.WriteLine("Task 2 starting");
19+
Console.WriteLine("Task 2 starting.");
2020
Thread.Sleep(1000);
21-
Console.WriteLine("Task 2 ending");
21+
Console.WriteLine("Task 2 ending.");
2222
}
2323

2424
static void Main(string[] args)
2525
{
26-
// The Task.Parallel class can be found in the System.Threading.Tasks namespace.
27-
// The Parallel.Invoke method accepts a number of Action delegates and creates a Task for each of them.
28-
// An action delegate is an encapsulation of a method that accepts no parameters and does not return a
29-
// result.
30-
// An action delegate can be replaced with a lambda expression.
31-
// Note that you have no control over the order in which the tasks are started or which processor they are
32-
// assigned to (e.g. Task1 might finish before Task2 and vice versa).
26+
/*
27+
28+
The Task.Parallel class can be found in the System.Threading.Tasks namespace.
29+
30+
The Parallel.Invoke method accepts a number of Action delegates and creates a Task for each of them.
31+
32+
An action delegate is an encapsulation of a method that accepts no parameters and does not return a
33+
result.
34+
35+
An action delegate can be replaced with a lambda expression.
36+
37+
Note that you have no control over the order in which the tasks are started or which processor they are
38+
assigned to (e.g. Task1 might finish before Task2 and vice versa).
39+
40+
*/
3341
Parallel.Invoke(() => Task1(), () => Task2());
3442

3543
Console.WriteLine("Finished processing. Press a key to end.");
3644
Console.ReadKey();
3745
}
3846
}
39-
}
47+
}

LISTING 1-10 Exceptions in PLINQ/LISTING 1-10 Exceptions in PLINQ/Program.cs

+6-2
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,11 @@ static void Main(string[] args)
4545

4646
try
4747
{
48-
// An AggregateException is thrown when all queries are completed if any query generates an exception.
48+
/*
49+
50+
An AggregateException is thrown when all queries are completed if any query generates an exception.
51+
52+
*/
4953
var result = from person in
5054
people.AsParallel()
5155
//where CheckCity(person.City)
@@ -62,4 +66,4 @@ where CheckCity(person.Name, person.City)
6266
Console.ReadKey();
6367
}
6468
}
65-
}
69+
}

LISTING 1-11 Create a task/LISTING 1-11 Create a task/Program.cs

+18-14
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,36 @@ class Program
88
{
99
public static void DoWork()
1010
{
11-
Console.WriteLine("Work starting");
11+
Console.WriteLine("Work starting.");
1212
Thread.Sleep(2000);
13-
Console.WriteLine("Work finished");
13+
Console.WriteLine("Work finished.");
1414
}
1515

1616
static void Main(string[] args)
1717
{
18-
// Create a task, start it and wait for it to complete.
18+
/*
19+
20+
Create a task, start it and wait for it to complete.
21+
22+
*/
1923
Task newTask = new Task(() => DoWork());
20-
Console.WriteLine("Task start (begin)");
24+
Console.WriteLine("Task start (begin).");
2125
newTask.Start();
22-
Console.WriteLine("Task start (end)");
23-
Console.WriteLine("Task wait (begin)");
26+
Console.WriteLine("Task start (end).");
27+
Console.WriteLine("Task wait (begin).");
2428
newTask.Wait();
25-
Console.WriteLine("Task wait (end)");
29+
Console.WriteLine("Task wait (end).");
2630

2731
/*
2832
29-
Task start (begin)
30-
Task start (end)
31-
Task wait (begin)
32-
Work starting
33-
Work finished
34-
Task wait (end)
33+
Task start (begin).
34+
Task start (end).
35+
Task wait (begin).
36+
Work starting.
37+
Work finished.
38+
Task wait (end).
3539
3640
*/
3741
}
3842
}
39-
}
43+
}

LISTING 1-12 Run a task/LISTING 1-12 Run a task/Program.cs

+18-14
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,35 @@ class Program
88
{
99
public static void DoWork()
1010
{
11-
Console.WriteLine("Work starting");
11+
Console.WriteLine("Work starting.");
1212
Thread.Sleep(2000);
13-
Console.WriteLine("Work finished");
13+
Console.WriteLine("Work finished.");
1414
}
1515

16-
// Run a task (create and start) and wait for it to complete.
16+
/*
17+
18+
Run a task (create and start) and wait for it to complete.
19+
20+
*/
1721
static void Main(string[] args)
1822
{
19-
Console.WriteLine("Task start (begin)");
23+
Console.WriteLine("Task start (begin).");
2024
Task newTask = Task.Run(() => DoWork());
21-
Console.WriteLine("Task start (end)");
22-
Console.WriteLine("Task wait (begin)");
25+
Console.WriteLine("Task start (end).");
26+
Console.WriteLine("Task wait (begin).");
2327
newTask.Wait();
24-
Console.WriteLine("Task wait (end)");
28+
Console.WriteLine("Task wait (end).");
2529

2630
/*
2731
28-
Task start (begin)
29-
Task start (end)
30-
Task wait (begin)
31-
Work starting
32-
Work finished
33-
Task wait (end)
32+
Task start (begin).
33+
Task start (end).
34+
Task wait (begin).
35+
Work starting.
36+
Work finished.
37+
Task wait (end).
3438
3539
*/
3640
}
3741
}
38-
}
42+
}

LISTING 1-13 Task Factory/LISTING 1-13 Task Factory/Program.cs

+17-11
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,20 @@
33
using System.Threading.Tasks;
44

55
namespace LISTING_1_13_Task_Factory
6+
{
7+
/*
68
7-
// This is a bonus example program that shows how to use the TaskFactory object.
8-
// Normally you'd use Task.Factory.StartNew or the thread pool in preference.
9-
// Task.Factory.StartNew is used in Listing 1-17 and the thread pool is described in Listing 1-28.
9+
This is a bonus example program that shows how to use the TaskFactory object.
1010
11-
// The example creates a task factory and uses it to create a task that runs until it completes.
12-
// If you press enter before five seconds have elapsed the task is terminated and the program ends.
13-
{
11+
Normally you'd use Task.Factory.StartNew or the thread pool in preference.
12+
13+
Task.Factory.StartNew is used in Listing 1-17 and the thread pool is described in Listing 1-28.
14+
15+
The example creates a task factory and uses it to create a task that runs until it completes.
16+
17+
If you press enter before five seconds have elapsed the task is terminated and the program ends.
18+
19+
*/
1420
class Program
1521
{
1622
static void Main(string[] args)
@@ -28,10 +34,10 @@ static void Main(string[] args)
2834
// Use the factory to create a new Task running do work.
2935
Task t2 = factory.StartNew(() => DoWork());
3036

31-
Console.WriteLine("Press enter to dispose of the task");
37+
Console.WriteLine("Press enter to dispose of the task.");
3238
Console.ReadLine();
3339

34-
Console.WriteLine("Disposing of the task");
40+
Console.WriteLine("Disposing of the task.");
3541

3642
// Cancel the task.
3743
// Dispose of the task using the cancellation token.
@@ -40,7 +46,7 @@ static void Main(string[] args)
4046

4147
static void DoWork()
4248
{
43-
Console.WriteLine("Doing work..");
49+
Console.WriteLine("Doing work.");
4450

4551
int total = 0;
4652

@@ -50,7 +56,7 @@ static void DoWork()
5056
total += i;
5157
}
5258

53-
Console.WriteLine("Result: " + total); // 12497500
59+
Console.WriteLine($"Result: {total}."); // 12497500
5460
}
5561
}
56-
}
62+
}

LISTING 1-13 Task returning a value/LISTING 1-13 Task returning a value/Program.cs

+22-14
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,40 @@ class Program
88
{
99
public static int CalculateResult()
1010
{
11-
Console.WriteLine("Work starting");
11+
Console.WriteLine("Work starting.");
1212
Thread.Sleep(2000);
13-
Console.WriteLine("Work finished");
13+
Console.WriteLine("Work finished.");
1414
return 99;
1515
}
1616
static void Main(string[] args)
1717
{
18-
// A task can be created that will return a value.
19-
// A program will wait for the task to deliver the result when the Result property of the Task instance is
20-
// read.
21-
// The Task.Run method uses the TaskFactory.StartNew method to create and start the task, using the default
22-
// task scheduler that uses the .NET framework thread pool.
23-
// The Task class exposes a Factory property that refers to the default task scheduler.
24-
// You can create your own task scheduler or run a task scheduler in the synchronization context of another
25-
// processor.
26-
// You can also create your own TaskFactory if you want to create a number of tasks with the same
27-
// configuration.
18+
/*
19+
20+
A task can be created that will return a value.
21+
22+
A program will wait for the task to deliver the result when the Result property of the Task instance is
23+
read.
24+
25+
The Task.Run method uses the TaskFactory.StartNew method to create and start the task, using the default
26+
task scheduler that uses the .NET framework thread pool.
27+
28+
The Task class exposes a Factory property that refers to the default task scheduler.
29+
30+
You can create your own task scheduler or run a task scheduler in the synchronization context of another
31+
processor.
32+
33+
You can also create your own TaskFactory if you want to create a number of tasks with the same
34+
configuration.
35+
36+
*/
2837
Task<int> task = Task.Run(() =>
2938
{
3039
return CalculateResult();
3140
});
32-
3341
Console.WriteLine(task.Result);
3442

3543
Console.WriteLine("Finished processing. Press a key to end.");
3644
Console.ReadKey();
3745
}
3846
}
39-
}
47+
}

LISTING 1-14 Task waitall/LISTING 1-14 Task waitall/Program.cs

+15-10
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ class Program
88
{
99
public static void DoWork(int i)
1010
{
11-
Console.WriteLine("Task {0} starting", i);
11+
Console.WriteLine($"Task {i} starting.");
1212
Thread.Sleep(2000);
13-
Console.WriteLine("Task {0} finished", i);
13+
Console.WriteLine($"Task {i} finished.");
1414
}
1515

1616
static void Main(string[] args)
@@ -19,21 +19,26 @@ static void Main(string[] args)
1919

2020
for (int i = 0; i < 10; i++)
2121
{
22-
int taskNum = i; // make a local copy of the loop counter so that the
23-
// correct task number is passed into the lambda function
22+
// make a local copy of loop counter so that the correct task number is passed into the lambda function
23+
int taskNum = i;
2424
Tasks[i] = Task.Run(() => DoWork(taskNum));
25-
//Tasks[i] = Task.Run(() => DoWork(i)); // all of the tasks would have number 10, which is the value of
26-
// the limit of the loop
25+
26+
// all of the tasks would have number 10, which is the value of the limit of the loop
27+
//Tasks[i] = Task.Run(() => DoWork(i));
2728
}
2829

29-
// The Task.WaitAll method can be used to pause a program until a number of tasks have completed.
30-
Task.WaitAll(Tasks);
30+
/*
31+
32+
The Task.WaitAll method can be used to pause a program until a number of tasks have completed.
33+
34+
The Task.WaitAny method can be used to pause a program until any of the tasks have completed.
3135
32-
// The Task.WaitAny method can be used to pause a program until any of the tasks have completed.
36+
*/
37+
Task.WaitAll(Tasks);
3338
//Task.WaitAny(Tasks);
3439

3540
Console.WriteLine("Finished processing. Press a key to end.");
3641
Console.ReadKey();
3742
}
3843
}
39-
}
44+
}

LISTING 1-15 Continuation tasks/LISTING 1-15 Continuation tasks/Program.cs

+19-10
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,29 @@ public static void WorldTask()
2020

2121
static void Main(string[] args)
2222
{
23-
// A continuous task can be nominated to start when an existing task (the antecedent task) finishes.
24-
// If the antecedent task produces a result, it can be supplied as an input to the continuation task.
25-
// Continuation tasks can be used to create a "pipeline" of operations, with each successive stage starting
26-
// when the preceding one ends.
27-
// A Task object exposes a ContinueWith method that can be used to specify a continuation task.
28-
// The lambda expression that executes the continuation task is provided with a reference to the antecedent
29-
// task, which it can use to determine if the antecedent completed successfully.
30-
// You can add continuation tasks to tasks that deliver a result, in which case the continuation task can
31-
// use the Result property of the antecedent task to obtain its input data.
23+
/*
24+
25+
A continuous task can be nominated to start when an existing task (the antecedent task) finishes.
26+
27+
If the antecedent task produces a result, it can be supplied as an input to the continuation task.
28+
29+
Continuation tasks can be used to create a "pipeline" of operations, with each successive stage starting
30+
when the preceding one ends.
31+
32+
A Task object exposes a ContinueWith method that can be used to specify a continuation task.
33+
34+
The lambda expression that executes the continuation task is provided with a reference to the antecedent
35+
task, which it can use to determine if the antecedent completed successfully.
36+
37+
You can add continuation tasks to tasks that deliver a result, in which case the continuation task can use
38+
the Result property of the antecedent task to obtain its input data.
39+
40+
*/
3241
Task task = Task.Run(() => HelloTask());
3342
task.ContinueWith( (prevTask) => WorldTask());
3443

3544
Console.WriteLine("Finished processing. Press a key to end.");
3645
Console.ReadKey();
3746
}
3847
}
39-
}
48+
}

0 commit comments

Comments
 (0)