SlideShare a Scribd company logo
Mohammad Shaker 
mohammadshaker.com 
@ZGTRShaker 
2011, 2012, 2013, 2014 
C# Advanced 
L04-THREADING
Threading
Concept of Threading 
•What is a “Thread”? 
–The advantage of threading is the ability to create applications that use more than one thread of execution. For example, a process can have a user interface thread that manages interactions with the user and worker threads that perform other tasks while the user interface thread waits for user input. 
•What’s this? 
for (int i = 1; i < 50; i++) 
{ 
Console.SetWindowSize(i, i); 
System.Threading.Thread.Sleep(50); 
}
Let’s Parallel
Let’s Parallel 
class Program 
{ 
private static void Main() 
{ 
for (int i = 0; i < 10; i++) 
{ 
long total = GetTotal(); 
Console.WriteLine("{0} -{1}", i, total); 
} 
} 
private static long GetTotal() 
{ 
long total = 0; 
for (inti= 1; i< 100000000; i++) 
{ 
total += i; 
} 
return total; 
} 
}
Let’s Parallel 
class Program 
{ 
private static void Main() 
{ 
for (int i = 0; i < 10; i++) 
{ 
long total = GetTotal(); 
Console.WriteLine("{0} -{1}", i, total); 
} 
} 
private static long GetTotal() 
{ 
long total = 0; 
for (inti= 1; i< 100000000; i++) 
{ 
total += i; 
} 
return total; 
} 
} 
0 -4999999950000000 
1 -4999999950000000 
2 -4999999950000000 
3 -4999999950000000 
4 -4999999950000000 
5 -4999999950000000 
6 -4999999950000000 
7 -4999999950000000 
8 -4999999950000000 
9 -4999999950000000 
Press any key to continue . . .
Let’s Parallel 
class Program 
{ 
private static void Main() 
{ 
for (int i = 0; i < 10; i++) 
{ 
long total = GetTotal(); 
Console.WriteLine("{0} -{1}", i, total); 
} 
} 
private static long GetTotal() 
{ 
long total = 0; 
for (inti= 1; i< 100000000; i++) 
{ 
total += i; 
} 
return total; 
} 
}
Let’s Parallel 
class Program 
{ 
private static void Main() 
{ 
Parallel.For(0, 10, i => 
{ 
long total = GetTotal(); 
Console.WriteLine("{0} -{1}", i, total); 
}); 
} 
private static long GetTotal() 
{ 
long total = 0; 
for (inti= 1; i< 100000000; i++) 
{ 
total += i; 
} 
return total; 
} 
}
Let’s Parallel 
class Program 
{ 
private static void Main() 
{ 
Parallel.For(0, 10, i => 
{ 
long total = GetTotal(); 
Console.WriteLine("{0} -{1}", i, total); 
}); 
} 
private static long GetTotal() 
{ 
long total = 0; 
for (inti= 1; i< 100000000; i++) 
{ 
total += i; 
} 
return total; 
} 
} 
0 -4999999950000000 
1 -4999999950000000 
2 -4999999950000000 
3 -4999999950000000 
4 -4999999950000000 
5 -4999999950000000 
6 -4999999950000000 
7 -4999999950000000 
8 -4999999950000000 
9 -4999999950000000 
Press any key to continue . . . 
The Same Result but Much Faster
Parallel Task
Let’s Parallel 
0 on Task 1 
2 on Task 1 
5 on Task 2 
10 on Task 3 
1 on Task 5 
4 on Task 5 
8 on Task 5 
15 on Task 4 
16 on Task 4 
17 on Task 4 
18 on Task 4 
19 on Task 4 
13 on Task 4 
14 on Task 4 
6 on Task 2 
7 on Task 2 
9 on Task 5 
11 on Task 3 
12 on Task 3 
3 on Task 1 
Press any key to continue . . . 
private void Test() 
{ 
Parallel.For(0, 20, i=> Console.WriteLine("{0} on Task {1}", i, Task.CurrentId)); 
} 
5different tasks working
Let’s Parallel 
0 on Task 1 
2 on Task 1 
5 on Task 2 
10 on Task 3 
1 on Task 5 
4 on Task 5 
8 on Task 5 
15 on Task 4 
16 on Task 4 
17 on Task 4 
18 on Task 4 
19 on Task 4 
13 on Task 4 
14 on Task 4 
6 on Task 2 
7 on Task 2 
9 on Task 5 
11 on Task 3 
12 on Task 3 
3 on Task 1 
Press any key to continue . . . 
private void Test() 
{ 
Parallel.For(0, 20, i=> Console.WriteLine("{0} on Task {1}", i, Task.CurrentId)); 
} 
0 on Task 1 
2 on Task 1 
5 on Task 2 
6 on Task 2 
10 on Task 3 
11 on Task 3 
12 on Task 3 
13 on Task 3 
14 on Task 3 
16 on Task 3 
3 on Task 1 
15 on Task 4 
8 on Task 4 
9 on Task 4 
7 on Task 2 
1 on Task 5 
17 on Task 3 
4 on Task 1 
18 on Task 3 
19 on Task 3 
Press any key to continue . . . 
0 on Task 1 
1 on Task 1 
5 on Task 2 
6 on Task 2 
7 on Task 2 
8 on Task 2 
9 on Task 2 
11 on Task 2 
12 on Task 2 
13 on Task 2 
15 on Task 4 
16 on Task 4 
17 on Task 4 
18 on Task 4 
19 on Task 4 
2 on Task 1 
4 on Task 4 
14 on Task 2 
10 on Task 3 
3 on Task 5 
Press any key to continue . . .
Let’s Parallel 
•The following: 
•Is the same as: 
private void Test() 
{ 
Parallel.For(0, 20, i=> 
{ 
Console.WriteLine("{0} on Task {1}", i, Task.CurrentId); 
}); 
} 
private void Test() 
{ 
Parallel.For(0, 20, i=> Console.WriteLine("{0} on Task {1}", i, Task.CurrentId)); 
}
Let’s Parallel 
0 on Task 1 
1 on Task 1 
2 on Task 1 
3 on Task 1 
4 on Task 1 
5 on Task 1 
6 on Task 1 
7 on Task 1 
8 on Task 1 
10 on Task 2 
11 on Task 2 
12 on Task 2 
13 on Task 2 
14 on Task 2 
15 on Task 2 
16 on Task 2 
9 on Task 1 
17 on Task 2 
18 on Task 2 
19 on Task 2 
Press any key to continue . . . 
ParallelOptionsparallelOptions= new ParallelOptions(); 
parallelOptions.MaxDegreeOfParallelism= 2; 
Parallel.For(0, 20, parallelOptions, i=> 
{ 
Console.WriteLine("{0} on Task {1}", i, Task.CurrentId); 
}); 
0 on Task 1 
1 on Task 1 
2 on Task 1 
3 on Task 1 
4 on Task 1 
10 on Task 2 
11 on Task 2 
12 on Task 2 
13 on Task 2 
14 on Task 2 
15 on Task 2 
16 on Task 2 
17 on Task 2 
18 on Task 2 
19 on Task 2 
7 on Task 2 
8 on Task 2 
9 on Task 2 
5 on Task 1 
6 on Task 1 
Press any key to continue . . . 
Limiting the number of tasks to just 2
Parallel.Invoke
Parallel.Invoke 
static void Main() 
{ 
Parallel.Invoke( 
() => RunTask(1), 
() => RunTask(2), 
() => RunTask(3), 
() => RunTask(4), 
() => RunTask(5) 
); 
} 
static void RunTask(inttaskNumber) 
{ 
Console.WriteLine("Task {0} started", taskNumber); 
Console.WriteLine("Task {0} complete", taskNumber); 
}
Parallel.Invoke 
static void Main() 
{ 
Parallel.Invoke( 
() => RunTask(1), 
() => RunTask(2), 
() => RunTask(3), 
() => RunTask(4), 
() => RunTask(5) 
); 
} 
static void RunTask(inttaskNumber) 
{ 
Console.WriteLine("Task {0} started", taskNumber); 
Console.WriteLine("Task {0} complete", taskNumber); 
} 
Task 2 started 
Task 2 complete 
Task 3 started 
Task 4 started 
Task 1 started 
Task 1 complete 
Task 3 complete 
Task 5 started 
Task 5 complete 
Task 4 complete 
Press any key to continue . . .
Parallel.Invoke 
static void Main() 
{ 
Parallel.Invoke( 
() => RunTask(1), 
() => RunTask(2), 
() => RunTask(3), 
() => RunTask(4), 
() => RunTask(5) 
); 
} 
static void RunTask(inttaskNumber) 
{ 
Console.WriteLine("Task {0} started", taskNumber); 
Console.WriteLine("Task {0} complete", taskNumber); 
} 
Task 2 started 
Task 2 complete 
Task 3 started 
Task 4 started 
Task 1 started 
Task 1 complete 
Task 3 complete 
Task 5 started 
Task 5 complete 
Task 4 complete 
Press any key to continue . . . 
Use the following to limit the number of concurrent tasks: 
ParallelOptionsparallelOptions= new ParallelOptions(); 
parallelOptions.MaxDegreeOfParallelism= 2;
Threading Problems, like,
Threading Problems 
class Program 
{ 
static int_counter = 0; 
static void Main(string[] args) 
{ 
Parallel.Invoke(AddOne, 
SubtractOne); 
Console.WriteLine("Final counter value is {0}.", _counter); 
} 
static void AddOne() 
{ 
inttemp = _counter; 
temp++; 
Thread.Sleep(2000); 
Console.WriteLine("Incremented counter to {0}.", temp); 
_counter = temp; 
} 
static void SubtractOne() 
{ 
inttemp = _counter; 
temp--; 
Thread.Sleep(2000); 
Console.WriteLine("Decremented counter to {0}.", temp); 
_counter = temp; 
} 
}
Threading Problems 
class Program 
{ 
static int_counter = 0; 
static void Main(string[] args) 
{ 
Parallel.Invoke(AddOne, 
SubtractOne); 
Console.WriteLine("Final counter value is {0}.", _counter); 
} 
static void AddOne() 
{ 
inttemp = _counter; 
temp++; 
Thread.Sleep(2000); 
Console.WriteLine("Incremented counter to {0}.", temp); 
_counter = temp; 
} 
static void SubtractOne() 
{ 
inttemp = _counter; 
temp--; 
Thread.Sleep(2000); 
Console.WriteLine("Decremented counter to {0}.", temp); 
_counter = temp; 
} 
} 
Incremented counter to 1. 
Decremented counter to -1. 
Final counter value is -1.
Threading Problems 
class Program 
{ 
static int_counter = 0; 
static void Main(string[] args) 
{ 
Parallel.Invoke(AddOne, 
SubtractOne); 
Console.WriteLine("Final counter value is {0}.", _counter); 
} 
static void AddOne() 
{ 
inttemp = _counter; 
temp++; 
Thread.Sleep(2000); 
Console.WriteLine("Incremented counter to {0}.", temp); 
_counter = temp; 
} 
static void SubtractOne() 
{ 
inttemp = _counter; 
temp--; 
Thread.Sleep(2000); 
Console.WriteLine("Decremented counter to {0}.", temp); 
_counter = temp; 
} 
} 
Incremented counter to 1. 
Decremented counter to -1. 
Final counter value is -1.
Threading Problems 
class Program 
{ 
static int_counter = 0; 
static void Main(string[] args) 
{ 
Parallel.Invoke(AddOne, 
SubtractOne); 
Console.WriteLine("Final counter value is {0}.", _counter); 
} 
static void AddOne() 
{ 
inttemp = _counter; 
temp++; 
Thread.Sleep(2000); 
Console.WriteLine("Incremented counter to {0}.", temp); 
_counter = temp; 
} 
static void SubtractOne() 
{ 
inttemp = _counter; 
temp--; 
Thread.Sleep(2000); 
Console.WriteLine("Decremented counter to {0}.", temp); 
_counter = temp; 
} 
} 
Incremented counter to 1. 
Decremented counter to -1. 
Final counter value is -1. 
Race Conditions
Racing ConditionsThe Solution
Threading Problems 
class Program 
{ 
static int_counter = 0; 
static object _lock = new object(); 
static void Main(string[] args) 
{ 
Parallel.Invoke(AddOne, 
SubtractOne); 
Console.WriteLine("Final counter value is {0}.", _counter); 
} 
static void AddOne() 
{ 
lock (_lock) 
{ 
inttemp = _counter; 
temp++; 
Thread.Sleep(2000); 
Console.WriteLine("Incremented counter to {0}.", temp); 
_counter = temp; 
} 
} 
static void SubtractOne() 
{ 
lock (_lock) 
{ 
inttemp = _counter; 
temp--; 
Thread.Sleep(2000); 
Console.WriteLine("Decremented counter to {0}.", temp); 
_counter = temp; 
} 
} 
} 
Race Conditions
Threading Problems 
class Program 
{ 
static int_counter = 0; 
static object _lock = new object(); 
static void Main(string[] args) 
{ 
Parallel.Invoke(AddOne, 
SubtractOne); 
Console.WriteLine("Final counter value is {0}.", _counter); 
} 
static void AddOne() 
{ 
lock (_lock) 
{ 
inttemp = _counter; 
temp++; 
Thread.Sleep(2000); 
Console.WriteLine("Incremented counter to {0}.", temp); 
_counter = temp; 
} 
} 
static void SubtractOne() 
{ 
lock (_lock) 
{ 
inttemp = _counter; 
temp--; 
Thread.Sleep(2000); 
Console.WriteLine("Decremented counter to {0}.", temp); 
_counter = temp; 
} 
} 
} 
Race Conditions 
New
Threading Problems 
class Program 
{ 
static int_counter = 0; 
static object _lock = new object(); 
static void Main(string[] args) 
{ 
Parallel.Invoke(AddOne, 
SubtractOne); 
Console.WriteLine("Final counter value is {0}.", _counter); 
} 
static void AddOne() 
{ 
lock (_lock) 
{ 
inttemp = _counter; 
temp++; 
Thread.Sleep(2000); 
Console.WriteLine("Incremented counter to {0}.", temp); 
_counter = temp; 
} 
} 
static void SubtractOne() 
{ 
lock (_lock) 
{ 
inttemp = _counter; 
temp--; 
Thread.Sleep(2000); 
Console.WriteLine("Decremented counter to {0}.", temp); 
_counter = temp; 
} 
} 
} 
Race Conditions 
Shared object
Threading Problems 
class Program 
{ 
static int_counter = 0; 
static object _lock = new object(); 
static void Main(string[] args) 
{ 
Parallel.Invoke(AddOne, 
SubtractOne); 
Console.WriteLine("Final counter value is {0}.", _counter); 
} 
static void AddOne() 
{ 
lock (_lock) 
{ 
inttemp = _counter; 
temp++; 
Thread.Sleep(2000); 
Console.WriteLine("Incremented counter to {0}.", temp); 
_counter = temp; 
} 
} 
static void SubtractOne() 
{ 
lock (_lock) 
{ 
inttemp = _counter; 
temp--; 
Thread.Sleep(2000); 
Console.WriteLine("Decremented counter to {0}.", temp); 
_counter = temp; 
} 
} 
} 
Race Conditions 
Locking the shared object for each thread
Threading Problems 
class Program 
{ 
static int_counter = 0; 
static object _lock = new object(); 
static void Main(string[] args) 
{ 
Parallel.Invoke(AddOne, 
SubtractOne); 
Console.WriteLine("Final counter value is {0}.", _counter); 
} 
static void AddOne() 
{ 
lock (_lock) 
{ 
inttemp = _counter; 
temp++; 
Thread.Sleep(2000); 
Console.WriteLine("Incremented counter to {0}.", temp); 
_counter = temp; 
} 
} 
static void SubtractOne() 
{ 
lock (_lock) 
{ 
inttemp = _counter; 
temp--; 
Thread.Sleep(2000); 
Console.WriteLine("Decremented counter to {0}.", temp); 
_counter = temp; 
} 
} 
} 
The right output 
Incremented counter to 1. 
Decremented counter to 0. 
Final counter value is 0.
Lock (Object)
Threading Problems 
class Program 
{ 
static int_counter = 0; 
static object _lock = new object(); 
static void Main(string[] args) 
{ 
Parallel.Invoke(AddOne, 
SubtractOne); 
Console.WriteLine("Final counter value is {0}.", _counter); 
} 
static void AddOne() 
{ 
lock (_lock) 
{ 
inttemp = _counter; 
temp++; 
Thread.Sleep(2000); 
Console.WriteLine("Incremented counter to {0}.", temp); 
_counter = temp; 
} 
} 
static void SubtractOne() 
{ 
lock (_lock) 
{ 
inttemp = _counter; 
temp--; 
Thread.Sleep(2000); 
Console.WriteLine("Decremented counter to {0}.", temp); 
_counter = temp; 
} 
} 
} 
Not good, don’t do this, or lock a string or etc.
Threading Problems 
class Program 
{ 
static int_counter = 0; 
static object _lock = new object(); 
static void Main(string[] args) 
{ 
Parallel.Invoke(AddOne, 
SubtractOne); 
Console.WriteLine("Final counter value is {0}.", _counter); 
} 
static void AddOne() 
{ 
lock (_lock) 
{ 
inttemp = _counter; 
temp++; 
Thread.Sleep(2000); 
Console.WriteLine("Incremented counter to {0}.", temp); 
_counter = temp; 
} 
} 
static void SubtractOne() 
{ 
lock (_lock) 
{ 
inttemp = _counter; 
temp--; 
Thread.Sleep(2000); 
Console.WriteLine("Decremented counter to {0}.", temp); 
_counter = temp; 
} 
} 
} 
The best choice for a locking object is a private or protected object defined within the class that controls the shared state.
ThreadClass
Threading Problems 
class Program 
{ 
static int_counter = 0; 
static object _lock = new object(); 
constintsleepAmount= 500; 
static void Main(string[] args) 
{ 
Thread tAdd= new Thread(AddOne); 
Thread tSub= new Thread(SubtractOne); 
tAdd.Start(); 
tSub.Start(); 
Console.WriteLine("Final counter value is {0}.", _counter); 
} 
static void AddOne() 
{ 
Monitor.Enter(_lock); 
try 
{ 
_counter++; 
Thread.Sleep(sleepAmount); 
Console.WriteLine("Incremented counter to {0}.", _counter); 
} 
finally { Monitor.Exit(_lock); } 
} 
static void SubtractOne() 
{ 
Monitor.Enter(_lock); 
try 
{ 
_counter--; 
Thread.Sleep(sleepAmount); 
Console.WriteLine("Decremented counter to {0}.", _counter); 
} 
finally { Monitor.Exit(_lock); } 
} 
} 
}
Threading Problems 
class Program 
{ 
static int_counter = 0; 
static object _lock = new object(); 
constintsleepAmount= 500; 
static void Main(string[] args) 
{ 
Thread tAdd= new Thread(AddOne); 
Thread tSub= new Thread(SubtractOne); 
tAdd.Start(); 
tSub.Start(); 
Console.WriteLine("Final counter value is {0}.", _counter); 
} 
static void AddOne() 
{ 
Monitor.Enter(_lock); 
try 
{ 
_counter++; 
Thread.Sleep(sleepAmount); 
Console.WriteLine("Incremented counter to {0}.", _counter); 
} 
finally { Monitor.Exit(_lock); } 
} 
static void SubtractOne() 
{ 
Monitor.Enter(_lock); 
try 
{ 
_counter--; 
Thread.Sleep(sleepAmount); 
Console.WriteLine("Decremented counter to {0}.", _counter); 
} 
finally { Monitor.Exit(_lock); } 
} 
} 
} 
Monitor Lock
Threading Problems 
class Program 
{ 
static int_counter = 0; 
static object _lock = new object(); 
constintsleepAmount= 500; 
static void Main(string[] args) 
{ 
Thread tAdd= new Thread(AddOne); 
Thread tSub= new Thread(SubtractOne); 
tAdd.Start(); 
tSub.Start(); 
Console.WriteLine("Final counter value is {0}.", _counter); 
} 
static void AddOne() 
{ 
Monitor.Enter(_lock); 
try 
{ 
_counter++; 
Thread.Sleep(sleepAmount); 
Console.WriteLine("Incremented counter to {0}.", _counter); 
} 
finally { Monitor.Exit(_lock); } 
} 
static void SubtractOne() 
{ 
Monitor.Enter(_lock); 
try 
{ 
_counter--; 
Thread.Sleep(sleepAmount); 
Console.WriteLine("Decremented counter to {0}.", _counter); 
} 
finally { Monitor.Exit(_lock); } 
} 
} 
} 
Acquire Lock
Threading Problems 
class Program 
{ 
static int_counter = 0; 
static object _lock = new object(); 
constintsleepAmount= 500; 
static void Main(string[] args) 
{ 
Thread tAdd= new Thread(AddOne); 
Thread tSub= new Thread(SubtractOne); 
tAdd.Start(); 
tSub.Start(); 
Console.WriteLine("Final counter value is {0}.", _counter); 
} 
static void AddOne() 
{ 
Monitor.Enter(_lock); 
try 
{ 
_counter++; 
Thread.Sleep(sleepAmount); 
Console.WriteLine("Incremented counter to {0}.", _counter); 
} 
finally { Monitor.Exit(_lock); } 
} 
static void SubtractOne() 
{ 
Monitor.Enter(_lock); 
try 
{ 
_counter--; 
Thread.Sleep(sleepAmount); 
Console.WriteLine("Decremented counter to {0}.", _counter); 
} 
finally { Monitor.Exit(_lock); } 
} 
} 
} 
Release Lock
Threading Problems 
class Program 
{ 
static int_counter = 0; 
static object _lock = new object(); 
constintsleepAmount= 500; 
static void Main(string[] args) 
{ 
Thread tAdd= new Thread(AddOne); 
Thread tSub= new Thread(SubtractOne); 
tAdd.Start(); 
tSub.Start(); 
Console.WriteLine("Final counter value is {0}.", _counter); 
} 
static void AddOne() 
{ 
Monitor.Enter(_lock); 
try 
{ 
_counter++; 
Thread.Sleep(sleepAmount); 
Console.WriteLine("Incremented counter to {0}.", _counter); 
} 
finally { Monitor.Exit(_lock); } 
} 
static void SubtractOne() 
{ 
Monitor.Enter(_lock); 
try 
{ 
_counter--; 
Thread.Sleep(sleepAmount); 
Console.WriteLine("Decremented counter to {0}.", _counter); 
} 
finally { Monitor.Exit(_lock); } 
} 
} 
} 
Final counter value is 0. 
Incremented counter to 1. 
Decremented counter to 0. 
Press any key to continue . . .
Threading Problems 
class Program 
{ 
static int_counter = 0; 
static object _lock = new object(); 
constintsleepAmount= 500; 
static void Main(string[] args) 
{ 
Thread tAdd= new Thread(AddOne); 
Thread tSub= new Thread(SubtractOne); 
tAdd.Start(); 
tSub.Start(); 
Console.WriteLine("Final counter value is {0}.", _counter); 
} 
static void AddOne() 
{ 
Monitor.Enter(_lock); 
try 
{ 
_counter++; 
Thread.Sleep(sleepAmount); 
Console.WriteLine("Incremented counter to {0}.", _counter); 
} 
finally { Monitor.Exit(_lock); } 
} 
static void SubtractOne() 
{ 
Monitor.Enter(_lock); 
try 
{ 
_counter--; 
Thread.Sleep(sleepAmount); 
Console.WriteLine("Decremented counter to {0}.", _counter); 
} 
finally { Monitor.Exit(_lock); } 
} 
} 
} 
Final counter value is 0. 
Incremented counter to 1. 
Decremented counter to 0. 
Press any key to continue . . . 
Why?
Threading Problems 
class Program 
{ 
static int_counter = 0; 
static object _lock = new object(); 
constintsleepAmount= 500; 
static void Main(string[] args) 
{ 
Thread tAdd= new Thread(AddOne); 
Thread tSub= new Thread(SubtractOne); 
tAdd.Start(); 
tSub.Start(); 
tAdd.Join(); 
tSub.Join(); 
Console.WriteLine("Final counter value is {0}.", _counter); 
} 
static void AddOne() 
{ 
Monitor.Enter(_lock); 
try 
{ 
_counter++; 
Thread.Sleep(sleepAmount); 
Console.WriteLine("Incremented counter to {0}.", _counter); 
} 
finally { Monitor.Exit(_lock); } 
} 
static void SubtractOne() 
{ 
Monitor.Enter(_lock); 
try 
{ 
_counter--; 
Thread.Sleep(sleepAmount); 
Console.WriteLine("Decremented counter to {0}.", _counter); 
} 
finally { Monitor.Exit(_lock); } 
} 
} 
} 
Blocks the calling thread until the thread terminates
Threading Problems 
class Program 
{ 
static int_counter = 0; 
static object _lock = new object(); 
constintsleepAmount= 500; 
static void Main(string[] args) 
{ 
Thread tAdd= new Thread(AddOne); 
Thread tSub= new Thread(SubtractOne); 
tAdd.Start(); 
tSub.Start(); 
tAdd.Join(); 
tSub.Join(); 
Console.WriteLine("Final counter value is {0}.", _counter); 
} 
static void AddOne() 
{ 
Monitor.Enter(_lock); 
try 
{ 
_counter++; 
Thread.Sleep(sleepAmount); 
Console.WriteLine("Incremented counter to {0}.", _counter); 
} 
finally { Monitor.Exit(_lock); } 
} 
static void SubtractOne() 
{ 
Monitor.Enter(_lock); 
try 
{ 
_counter--; 
Thread.Sleep(sleepAmount); 
Console.WriteLine("Decremented counter to {0}.", _counter); 
} 
finally { Monitor.Exit(_lock); } 
} 
} 
} 
Incremented counter to 1. 
Decremented counter to 0. 
Final counter value is 0. 
Press any key to continue . . . 
Blocks the calling thread until the thread terminates
Task.Factory 
varmyTask= Task.Factory.StartNew(() => { return "Hello, world!"; }); 
Console.WriteLine(myTask.Result);
TastWait
Wait 
int[] values = null; 
Task loadDataTask= new Task(() => 
{ 
Console.WriteLine("Loading data..."); 
Thread.Sleep(5000); 
values = Enumerable.Range(1,10).ToArray(); 
}); 
loadDataTask.Start(); 
Console.WriteLine("Data total = {0}", values.Sum());
Wait 
int[] values = null; 
Task loadDataTask= new Task(() => 
{ 
Console.WriteLine("Loading data..."); 
Thread.Sleep(5000); 
values = Enumerable.Range(1,10).ToArray(); 
}); 
loadDataTask.Start(); 
Console.WriteLine("Data total = {0}", values.Sum()); 
Will throw ArgumentNullExceptionbecause we are trying to use the array before it has been populated by the parallel task.
Wait 
int[] values = null; 
Task loadDataTask= new Task(() => 
{ 
Console.WriteLine("Loading data..."); 
Thread.Sleep(5000); 
values = Enumerable.Range(1,10).ToArray(); 
}); 
loadDataTask.Start(); 
Console.WriteLine("Data total = {0}", values.Sum()); 
Will throw ArgumentNullExceptionbecause we are trying to use the array before it has been populated by the parallel task. 
int[] values = null; 
Task loadDataTask= new Task(() => 
{ 
Console.WriteLine("Loading data..."); 
Thread.Sleep(5000); 
values = Enumerable.Range(1,10).ToArray(); 
}); 
loadDataTask.Start(); 
loadDataTask.Wait(); 
loadDataTask.Dispose(); 
Console.WriteLine("Data total = {0}", values.Sum()); // Data total = 55
int[] values = null; 
Task loadDataTask= new Task(() => 
{ 
Console.WriteLine("Loading data..."); 
Thread.Sleep(5000); 
values = Enumerable.Range(1,10).ToArray(); 
}); 
loadDataTask.Start(); 
loadDataTask.Wait(); 
loadDataTask.Dispose(); 
Console.WriteLine("Data total = {0}", values.Sum()); // Data total = 55 
Wait 
int[] values = null; 
Task loadDataTask= new Task(() => 
{ 
Console.WriteLine("Loading data..."); 
Thread.Sleep(5000); 
values = Enumerable.Range(1,10).ToArray(); 
}); 
loadDataTask.Start(); 
Console.WriteLine("Data total = {0}", values.Sum()); 
To fix it, we will now waitfor the task to be done
int[] values = null; 
Task loadDataTask= new Task(() => 
{ 
Console.WriteLine("Loading data..."); 
Thread.Sleep(5000); 
values = Enumerable.Range(1,10).ToArray(); 
}); 
loadDataTask.Start(); 
loadDataTask.Wait(); 
loadDataTask.Dispose(); 
Console.WriteLine("Data total = {0}", values.Sum()); 
Wait 
int[] values = null; 
Task loadDataTask= new Task(() => 
{ 
Console.WriteLine("Loading data..."); 
Thread.Sleep(5000); 
values = Enumerable.Range(1,10).ToArray(); 
}); 
loadDataTask.Start(); 
Console.WriteLine("Data total = {0}", values.Sum()); 
The output will be Data total = 55
Tasks Continuation 
Task continuation = firstTask.ContinueWith(antecedent => { /* functionality */ });

More Related Content

What's hot (17)

PPTX
CSharp for Unity Day2
Duong Thanh
 
PDF
GenServer in action
Yurii Bodarev
 
PPTX
The secret unit testing tools no one ever told you about
Dror Helper
 
PPTX
Tools and Techniques for Understanding Threading Behavior in Android*
Intel® Software
 
PDF
Completable future
Srinivasan Raghvan
 
PDF
The Ring programming language version 1.6 book - Part 7 of 189
Mahmoud Samir Fayed
 
PPTX
From clever code to better code
Dror Helper
 
PPTX
Java весна 2013 лекция 2
Technopark
 
PDF
The Ring programming language version 1.6 book - Part 184 of 189
Mahmoud Samir Fayed
 
PDF
Leveraging Completable Futures to handle your query results Asynchrhonously
David Gómez García
 
PDF
Actor Concurrency
Alex Miller
 
PDF
The Ring programming language version 1.7 book - Part 85 of 196
Mahmoud Samir Fayed
 
PDF
STAMP Descartes Presentation
STAMP Project
 
PDF
The Ring programming language version 1.8 book - Part 32 of 202
Mahmoud Samir Fayed
 
PDF
Java 7 LavaJUG
julien.ponge
 
PDF
The Ring programming language version 1.8 book - Part 88 of 202
Mahmoud Samir Fayed
 
PDF
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
julien.ponge
 
CSharp for Unity Day2
Duong Thanh
 
GenServer in action
Yurii Bodarev
 
The secret unit testing tools no one ever told you about
Dror Helper
 
Tools and Techniques for Understanding Threading Behavior in Android*
Intel® Software
 
Completable future
Srinivasan Raghvan
 
The Ring programming language version 1.6 book - Part 7 of 189
Mahmoud Samir Fayed
 
From clever code to better code
Dror Helper
 
Java весна 2013 лекция 2
Technopark
 
The Ring programming language version 1.6 book - Part 184 of 189
Mahmoud Samir Fayed
 
Leveraging Completable Futures to handle your query results Asynchrhonously
David Gómez García
 
Actor Concurrency
Alex Miller
 
The Ring programming language version 1.7 book - Part 85 of 196
Mahmoud Samir Fayed
 
STAMP Descartes Presentation
STAMP Project
 
The Ring programming language version 1.8 book - Part 32 of 202
Mahmoud Samir Fayed
 
Java 7 LavaJUG
julien.ponge
 
The Ring programming language version 1.8 book - Part 88 of 202
Mahmoud Samir Fayed
 
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
julien.ponge
 

Viewers also liked (17)

PDF
Threading in c#
gohsiauken
 
PPTX
Threading
abhay singh
 
PPTX
multi threading
Yaswanth Babu Gummadivelli
 
PPTX
Threading in C#
Medhat Dawoud
 
PPT
Threads c sharp
Karthick Suresh
 
PPTX
Multi threading design pattern
Yan Wang
 
PDF
Real time web
Medhat Dawoud
 
PPS
07 iec t1_s1_oo_ps_session_10
Niit Care
 
PPT
Threads c sharp
Deivaa
 
PPT
Intro To .Net Threads
rchakra
 
PPTX
Generics C#
Raghuveer Guthikonda
 
PPTX
Multithreading Design Patterns
PostSharp Technologies
 
PDF
C# Delegates and Event Handling
Jussi Pohjolainen
 
PPTX
Delegates and events
Gayathri Ganesh
 
ODP
Multithreading 101
Tim Penhey
 
PDF
Multithreading done right
Platonov Sergey
 
Threading in c#
gohsiauken
 
Threading
abhay singh
 
Threading in C#
Medhat Dawoud
 
Threads c sharp
Karthick Suresh
 
Multi threading design pattern
Yan Wang
 
Real time web
Medhat Dawoud
 
07 iec t1_s1_oo_ps_session_10
Niit Care
 
Threads c sharp
Deivaa
 
Intro To .Net Threads
rchakra
 
Multithreading Design Patterns
PostSharp Technologies
 
C# Delegates and Event Handling
Jussi Pohjolainen
 
Delegates and events
Gayathri Ganesh
 
Multithreading 101
Tim Penhey
 
Multithreading done right
Platonov Sergey
 
Ad

Similar to C# Advanced L04-Threading (20)

PPTX
Flow Control and Exception Handling.pptx
Sheetal343198
 
PPT
C Sharp Jn (3)
jahanullah
 
DOCX
.net progrmming part1
Dr.M.Karthika parthasarathy
 
PPTX
Python programming workshop session 2
Abdul Haseeb
 
PDF
04-Looping( For , while and do while looping) .pdf
nithishkumar2867
 
PPT
Loops
Kamran
 
PDF
The output should now look like this Row 1 sum 30 Row 2 sum.pdf
xlynettalampleyxc
 
PPTX
MUST CS101 Lab11
Ayman Hassan
 
PDF
soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin
soft-shake.ch
 
PPTX
C# Loops
guestae0484
 
DOCX
Parallel Programming With Dot Net
Neeraj Kaushik
 
PDF
C++ L03-Control Structure
Mohammad Shaker
 
PPT
Whats new in_csharp4
Abed Bukhari
 
PDF
.NET Multithreading and File I/O
Jussi Pohjolainen
 
PPTX
C#.net
vnboghani
 
PDF
C++ Course - Lesson 2
Mohamed Ahmed
 
PPTX
Dts x dicoding #2 memulai pemrograman kotlin
Ahmad Arif Faizin
 
PPT
Thread
phanleson
 
PDF
Java 7 at SoftShake 2011
julien.ponge
 
KEY
Why Learn Python?
Christine Cheung
 
Flow Control and Exception Handling.pptx
Sheetal343198
 
C Sharp Jn (3)
jahanullah
 
.net progrmming part1
Dr.M.Karthika parthasarathy
 
Python programming workshop session 2
Abdul Haseeb
 
04-Looping( For , while and do while looping) .pdf
nithishkumar2867
 
Loops
Kamran
 
The output should now look like this Row 1 sum 30 Row 2 sum.pdf
xlynettalampleyxc
 
MUST CS101 Lab11
Ayman Hassan
 
soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin
soft-shake.ch
 
C# Loops
guestae0484
 
Parallel Programming With Dot Net
Neeraj Kaushik
 
C++ L03-Control Structure
Mohammad Shaker
 
Whats new in_csharp4
Abed Bukhari
 
.NET Multithreading and File I/O
Jussi Pohjolainen
 
C#.net
vnboghani
 
C++ Course - Lesson 2
Mohamed Ahmed
 
Dts x dicoding #2 memulai pemrograman kotlin
Ahmad Arif Faizin
 
Thread
phanleson
 
Java 7 at SoftShake 2011
julien.ponge
 
Why Learn Python?
Christine Cheung
 
Ad

More from Mohammad Shaker (20)

PDF
12 Rules You Should to Know as a Syrian Graduate
Mohammad Shaker
 
PDF
Ultra Fast, Cross Genre, Procedural Content Generation in Games [Master Thesis]
Mohammad Shaker
 
PDF
Interaction Design L06 - Tricks with Psychology
Mohammad Shaker
 
PDF
Short, Matters, Love - Passioneers Event 2015
Mohammad Shaker
 
PDF
Unity L01 - Game Development
Mohammad Shaker
 
PDF
Android L07 - Touch, Screen and Wearables
Mohammad Shaker
 
PDF
Interaction Design L03 - Color
Mohammad Shaker
 
PDF
Interaction Design L05 - Typography
Mohammad Shaker
 
PDF
Interaction Design L04 - Materialise and Coupling
Mohammad Shaker
 
PDF
Android L05 - Storage
Mohammad Shaker
 
PDF
Android L04 - Notifications and Threading
Mohammad Shaker
 
PDF
Android L09 - Windows Phone and iOS
Mohammad Shaker
 
PDF
Interaction Design L01 - Mobile Constraints
Mohammad Shaker
 
PDF
Interaction Design L02 - Pragnanz and Grids
Mohammad Shaker
 
PDF
Android L10 - Stores and Gaming
Mohammad Shaker
 
PDF
Android L06 - Cloud / Parse
Mohammad Shaker
 
PDF
Android L08 - Google Maps and Utilities
Mohammad Shaker
 
PDF
Android L03 - Styles and Themes
Mohammad Shaker
 
PDF
Android L02 - Activities and Adapters
Mohammad Shaker
 
PDF
Android L01 - Warm Up
Mohammad Shaker
 
12 Rules You Should to Know as a Syrian Graduate
Mohammad Shaker
 
Ultra Fast, Cross Genre, Procedural Content Generation in Games [Master Thesis]
Mohammad Shaker
 
Interaction Design L06 - Tricks with Psychology
Mohammad Shaker
 
Short, Matters, Love - Passioneers Event 2015
Mohammad Shaker
 
Unity L01 - Game Development
Mohammad Shaker
 
Android L07 - Touch, Screen and Wearables
Mohammad Shaker
 
Interaction Design L03 - Color
Mohammad Shaker
 
Interaction Design L05 - Typography
Mohammad Shaker
 
Interaction Design L04 - Materialise and Coupling
Mohammad Shaker
 
Android L05 - Storage
Mohammad Shaker
 
Android L04 - Notifications and Threading
Mohammad Shaker
 
Android L09 - Windows Phone and iOS
Mohammad Shaker
 
Interaction Design L01 - Mobile Constraints
Mohammad Shaker
 
Interaction Design L02 - Pragnanz and Grids
Mohammad Shaker
 
Android L10 - Stores and Gaming
Mohammad Shaker
 
Android L06 - Cloud / Parse
Mohammad Shaker
 
Android L08 - Google Maps and Utilities
Mohammad Shaker
 
Android L03 - Styles and Themes
Mohammad Shaker
 
Android L02 - Activities and Adapters
Mohammad Shaker
 
Android L01 - Warm Up
Mohammad Shaker
 

Recently uploaded (20)

PDF
Alarm in Android-Scheduling Timed Tasks Using AlarmManager in Android.pdf
Nabin Dhakal
 
PDF
Linux Certificate of Completion - LabEx Certificate
VICTOR MAESTRE RAMIREZ
 
PDF
4K Video Downloader Plus Pro Crack for MacOS New Download 2025
bashirkhan333g
 
PDF
IDM Crack with Internet Download Manager 6.42 Build 43 with Patch Latest 2025
bashirkhan333g
 
PPTX
Agentic Automation Journey Session 1/5: Context Grounding and Autopilot for E...
klpathrudu
 
PDF
Alexander Marshalov - How to use AI Assistants with your Monitoring system Q2...
VictoriaMetrics
 
PDF
Wondershare PDFelement Pro Crack for MacOS New Version Latest 2025
bashirkhan333g
 
PPTX
ChiSquare Procedure in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
SAP Firmaya İade ABAB Kodları - ABAB ile yazılmıl hazır kod örneği
Salih Küçük
 
PDF
MiniTool Partition Wizard Free Crack + Full Free Download 2025
bashirkhan333g
 
PDF
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
PDF
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
PPTX
Agentic Automation: Build & Deploy Your First UiPath Agent
klpathrudu
 
PDF
Open Chain Q2 Steering Committee Meeting - 2025-06-25
Shane Coughlan
 
PPTX
AEM User Group: India Chapter Kickoff Meeting
jennaf3
 
PPTX
Why Businesses Are Switching to Open Source Alternatives to Crystal Reports.pptx
Varsha Nayak
 
PDF
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
PPTX
Migrating Millions of Users with Debezium, Apache Kafka, and an Acyclic Synch...
MD Sayem Ahmed
 
PDF
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
PDF
Digger Solo: Semantic search and maps for your local files
seanpedersen96
 
Alarm in Android-Scheduling Timed Tasks Using AlarmManager in Android.pdf
Nabin Dhakal
 
Linux Certificate of Completion - LabEx Certificate
VICTOR MAESTRE RAMIREZ
 
4K Video Downloader Plus Pro Crack for MacOS New Download 2025
bashirkhan333g
 
IDM Crack with Internet Download Manager 6.42 Build 43 with Patch Latest 2025
bashirkhan333g
 
Agentic Automation Journey Session 1/5: Context Grounding and Autopilot for E...
klpathrudu
 
Alexander Marshalov - How to use AI Assistants with your Monitoring system Q2...
VictoriaMetrics
 
Wondershare PDFelement Pro Crack for MacOS New Version Latest 2025
bashirkhan333g
 
ChiSquare Procedure in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
SAP Firmaya İade ABAB Kodları - ABAB ile yazılmıl hazır kod örneği
Salih Küçük
 
MiniTool Partition Wizard Free Crack + Full Free Download 2025
bashirkhan333g
 
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
Agentic Automation: Build & Deploy Your First UiPath Agent
klpathrudu
 
Open Chain Q2 Steering Committee Meeting - 2025-06-25
Shane Coughlan
 
AEM User Group: India Chapter Kickoff Meeting
jennaf3
 
Why Businesses Are Switching to Open Source Alternatives to Crystal Reports.pptx
Varsha Nayak
 
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
Migrating Millions of Users with Debezium, Apache Kafka, and an Acyclic Synch...
MD Sayem Ahmed
 
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
Digger Solo: Semantic search and maps for your local files
seanpedersen96
 

C# Advanced L04-Threading

  • 1. Mohammad Shaker mohammadshaker.com @ZGTRShaker 2011, 2012, 2013, 2014 C# Advanced L04-THREADING
  • 3. Concept of Threading •What is a “Thread”? –The advantage of threading is the ability to create applications that use more than one thread of execution. For example, a process can have a user interface thread that manages interactions with the user and worker threads that perform other tasks while the user interface thread waits for user input. •What’s this? for (int i = 1; i < 50; i++) { Console.SetWindowSize(i, i); System.Threading.Thread.Sleep(50); }
  • 5. Let’s Parallel class Program { private static void Main() { for (int i = 0; i < 10; i++) { long total = GetTotal(); Console.WriteLine("{0} -{1}", i, total); } } private static long GetTotal() { long total = 0; for (inti= 1; i< 100000000; i++) { total += i; } return total; } }
  • 6. Let’s Parallel class Program { private static void Main() { for (int i = 0; i < 10; i++) { long total = GetTotal(); Console.WriteLine("{0} -{1}", i, total); } } private static long GetTotal() { long total = 0; for (inti= 1; i< 100000000; i++) { total += i; } return total; } } 0 -4999999950000000 1 -4999999950000000 2 -4999999950000000 3 -4999999950000000 4 -4999999950000000 5 -4999999950000000 6 -4999999950000000 7 -4999999950000000 8 -4999999950000000 9 -4999999950000000 Press any key to continue . . .
  • 7. Let’s Parallel class Program { private static void Main() { for (int i = 0; i < 10; i++) { long total = GetTotal(); Console.WriteLine("{0} -{1}", i, total); } } private static long GetTotal() { long total = 0; for (inti= 1; i< 100000000; i++) { total += i; } return total; } }
  • 8. Let’s Parallel class Program { private static void Main() { Parallel.For(0, 10, i => { long total = GetTotal(); Console.WriteLine("{0} -{1}", i, total); }); } private static long GetTotal() { long total = 0; for (inti= 1; i< 100000000; i++) { total += i; } return total; } }
  • 9. Let’s Parallel class Program { private static void Main() { Parallel.For(0, 10, i => { long total = GetTotal(); Console.WriteLine("{0} -{1}", i, total); }); } private static long GetTotal() { long total = 0; for (inti= 1; i< 100000000; i++) { total += i; } return total; } } 0 -4999999950000000 1 -4999999950000000 2 -4999999950000000 3 -4999999950000000 4 -4999999950000000 5 -4999999950000000 6 -4999999950000000 7 -4999999950000000 8 -4999999950000000 9 -4999999950000000 Press any key to continue . . . The Same Result but Much Faster
  • 11. Let’s Parallel 0 on Task 1 2 on Task 1 5 on Task 2 10 on Task 3 1 on Task 5 4 on Task 5 8 on Task 5 15 on Task 4 16 on Task 4 17 on Task 4 18 on Task 4 19 on Task 4 13 on Task 4 14 on Task 4 6 on Task 2 7 on Task 2 9 on Task 5 11 on Task 3 12 on Task 3 3 on Task 1 Press any key to continue . . . private void Test() { Parallel.For(0, 20, i=> Console.WriteLine("{0} on Task {1}", i, Task.CurrentId)); } 5different tasks working
  • 12. Let’s Parallel 0 on Task 1 2 on Task 1 5 on Task 2 10 on Task 3 1 on Task 5 4 on Task 5 8 on Task 5 15 on Task 4 16 on Task 4 17 on Task 4 18 on Task 4 19 on Task 4 13 on Task 4 14 on Task 4 6 on Task 2 7 on Task 2 9 on Task 5 11 on Task 3 12 on Task 3 3 on Task 1 Press any key to continue . . . private void Test() { Parallel.For(0, 20, i=> Console.WriteLine("{0} on Task {1}", i, Task.CurrentId)); } 0 on Task 1 2 on Task 1 5 on Task 2 6 on Task 2 10 on Task 3 11 on Task 3 12 on Task 3 13 on Task 3 14 on Task 3 16 on Task 3 3 on Task 1 15 on Task 4 8 on Task 4 9 on Task 4 7 on Task 2 1 on Task 5 17 on Task 3 4 on Task 1 18 on Task 3 19 on Task 3 Press any key to continue . . . 0 on Task 1 1 on Task 1 5 on Task 2 6 on Task 2 7 on Task 2 8 on Task 2 9 on Task 2 11 on Task 2 12 on Task 2 13 on Task 2 15 on Task 4 16 on Task 4 17 on Task 4 18 on Task 4 19 on Task 4 2 on Task 1 4 on Task 4 14 on Task 2 10 on Task 3 3 on Task 5 Press any key to continue . . .
  • 13. Let’s Parallel •The following: •Is the same as: private void Test() { Parallel.For(0, 20, i=> { Console.WriteLine("{0} on Task {1}", i, Task.CurrentId); }); } private void Test() { Parallel.For(0, 20, i=> Console.WriteLine("{0} on Task {1}", i, Task.CurrentId)); }
  • 14. Let’s Parallel 0 on Task 1 1 on Task 1 2 on Task 1 3 on Task 1 4 on Task 1 5 on Task 1 6 on Task 1 7 on Task 1 8 on Task 1 10 on Task 2 11 on Task 2 12 on Task 2 13 on Task 2 14 on Task 2 15 on Task 2 16 on Task 2 9 on Task 1 17 on Task 2 18 on Task 2 19 on Task 2 Press any key to continue . . . ParallelOptionsparallelOptions= new ParallelOptions(); parallelOptions.MaxDegreeOfParallelism= 2; Parallel.For(0, 20, parallelOptions, i=> { Console.WriteLine("{0} on Task {1}", i, Task.CurrentId); }); 0 on Task 1 1 on Task 1 2 on Task 1 3 on Task 1 4 on Task 1 10 on Task 2 11 on Task 2 12 on Task 2 13 on Task 2 14 on Task 2 15 on Task 2 16 on Task 2 17 on Task 2 18 on Task 2 19 on Task 2 7 on Task 2 8 on Task 2 9 on Task 2 5 on Task 1 6 on Task 1 Press any key to continue . . . Limiting the number of tasks to just 2
  • 16. Parallel.Invoke static void Main() { Parallel.Invoke( () => RunTask(1), () => RunTask(2), () => RunTask(3), () => RunTask(4), () => RunTask(5) ); } static void RunTask(inttaskNumber) { Console.WriteLine("Task {0} started", taskNumber); Console.WriteLine("Task {0} complete", taskNumber); }
  • 17. Parallel.Invoke static void Main() { Parallel.Invoke( () => RunTask(1), () => RunTask(2), () => RunTask(3), () => RunTask(4), () => RunTask(5) ); } static void RunTask(inttaskNumber) { Console.WriteLine("Task {0} started", taskNumber); Console.WriteLine("Task {0} complete", taskNumber); } Task 2 started Task 2 complete Task 3 started Task 4 started Task 1 started Task 1 complete Task 3 complete Task 5 started Task 5 complete Task 4 complete Press any key to continue . . .
  • 18. Parallel.Invoke static void Main() { Parallel.Invoke( () => RunTask(1), () => RunTask(2), () => RunTask(3), () => RunTask(4), () => RunTask(5) ); } static void RunTask(inttaskNumber) { Console.WriteLine("Task {0} started", taskNumber); Console.WriteLine("Task {0} complete", taskNumber); } Task 2 started Task 2 complete Task 3 started Task 4 started Task 1 started Task 1 complete Task 3 complete Task 5 started Task 5 complete Task 4 complete Press any key to continue . . . Use the following to limit the number of concurrent tasks: ParallelOptionsparallelOptions= new ParallelOptions(); parallelOptions.MaxDegreeOfParallelism= 2;
  • 20. Threading Problems class Program { static int_counter = 0; static void Main(string[] args) { Parallel.Invoke(AddOne, SubtractOne); Console.WriteLine("Final counter value is {0}.", _counter); } static void AddOne() { inttemp = _counter; temp++; Thread.Sleep(2000); Console.WriteLine("Incremented counter to {0}.", temp); _counter = temp; } static void SubtractOne() { inttemp = _counter; temp--; Thread.Sleep(2000); Console.WriteLine("Decremented counter to {0}.", temp); _counter = temp; } }
  • 21. Threading Problems class Program { static int_counter = 0; static void Main(string[] args) { Parallel.Invoke(AddOne, SubtractOne); Console.WriteLine("Final counter value is {0}.", _counter); } static void AddOne() { inttemp = _counter; temp++; Thread.Sleep(2000); Console.WriteLine("Incremented counter to {0}.", temp); _counter = temp; } static void SubtractOne() { inttemp = _counter; temp--; Thread.Sleep(2000); Console.WriteLine("Decremented counter to {0}.", temp); _counter = temp; } } Incremented counter to 1. Decremented counter to -1. Final counter value is -1.
  • 22. Threading Problems class Program { static int_counter = 0; static void Main(string[] args) { Parallel.Invoke(AddOne, SubtractOne); Console.WriteLine("Final counter value is {0}.", _counter); } static void AddOne() { inttemp = _counter; temp++; Thread.Sleep(2000); Console.WriteLine("Incremented counter to {0}.", temp); _counter = temp; } static void SubtractOne() { inttemp = _counter; temp--; Thread.Sleep(2000); Console.WriteLine("Decremented counter to {0}.", temp); _counter = temp; } } Incremented counter to 1. Decremented counter to -1. Final counter value is -1.
  • 23. Threading Problems class Program { static int_counter = 0; static void Main(string[] args) { Parallel.Invoke(AddOne, SubtractOne); Console.WriteLine("Final counter value is {0}.", _counter); } static void AddOne() { inttemp = _counter; temp++; Thread.Sleep(2000); Console.WriteLine("Incremented counter to {0}.", temp); _counter = temp; } static void SubtractOne() { inttemp = _counter; temp--; Thread.Sleep(2000); Console.WriteLine("Decremented counter to {0}.", temp); _counter = temp; } } Incremented counter to 1. Decremented counter to -1. Final counter value is -1. Race Conditions
  • 25. Threading Problems class Program { static int_counter = 0; static object _lock = new object(); static void Main(string[] args) { Parallel.Invoke(AddOne, SubtractOne); Console.WriteLine("Final counter value is {0}.", _counter); } static void AddOne() { lock (_lock) { inttemp = _counter; temp++; Thread.Sleep(2000); Console.WriteLine("Incremented counter to {0}.", temp); _counter = temp; } } static void SubtractOne() { lock (_lock) { inttemp = _counter; temp--; Thread.Sleep(2000); Console.WriteLine("Decremented counter to {0}.", temp); _counter = temp; } } } Race Conditions
  • 26. Threading Problems class Program { static int_counter = 0; static object _lock = new object(); static void Main(string[] args) { Parallel.Invoke(AddOne, SubtractOne); Console.WriteLine("Final counter value is {0}.", _counter); } static void AddOne() { lock (_lock) { inttemp = _counter; temp++; Thread.Sleep(2000); Console.WriteLine("Incremented counter to {0}.", temp); _counter = temp; } } static void SubtractOne() { lock (_lock) { inttemp = _counter; temp--; Thread.Sleep(2000); Console.WriteLine("Decremented counter to {0}.", temp); _counter = temp; } } } Race Conditions New
  • 27. Threading Problems class Program { static int_counter = 0; static object _lock = new object(); static void Main(string[] args) { Parallel.Invoke(AddOne, SubtractOne); Console.WriteLine("Final counter value is {0}.", _counter); } static void AddOne() { lock (_lock) { inttemp = _counter; temp++; Thread.Sleep(2000); Console.WriteLine("Incremented counter to {0}.", temp); _counter = temp; } } static void SubtractOne() { lock (_lock) { inttemp = _counter; temp--; Thread.Sleep(2000); Console.WriteLine("Decremented counter to {0}.", temp); _counter = temp; } } } Race Conditions Shared object
  • 28. Threading Problems class Program { static int_counter = 0; static object _lock = new object(); static void Main(string[] args) { Parallel.Invoke(AddOne, SubtractOne); Console.WriteLine("Final counter value is {0}.", _counter); } static void AddOne() { lock (_lock) { inttemp = _counter; temp++; Thread.Sleep(2000); Console.WriteLine("Incremented counter to {0}.", temp); _counter = temp; } } static void SubtractOne() { lock (_lock) { inttemp = _counter; temp--; Thread.Sleep(2000); Console.WriteLine("Decremented counter to {0}.", temp); _counter = temp; } } } Race Conditions Locking the shared object for each thread
  • 29. Threading Problems class Program { static int_counter = 0; static object _lock = new object(); static void Main(string[] args) { Parallel.Invoke(AddOne, SubtractOne); Console.WriteLine("Final counter value is {0}.", _counter); } static void AddOne() { lock (_lock) { inttemp = _counter; temp++; Thread.Sleep(2000); Console.WriteLine("Incremented counter to {0}.", temp); _counter = temp; } } static void SubtractOne() { lock (_lock) { inttemp = _counter; temp--; Thread.Sleep(2000); Console.WriteLine("Decremented counter to {0}.", temp); _counter = temp; } } } The right output Incremented counter to 1. Decremented counter to 0. Final counter value is 0.
  • 31. Threading Problems class Program { static int_counter = 0; static object _lock = new object(); static void Main(string[] args) { Parallel.Invoke(AddOne, SubtractOne); Console.WriteLine("Final counter value is {0}.", _counter); } static void AddOne() { lock (_lock) { inttemp = _counter; temp++; Thread.Sleep(2000); Console.WriteLine("Incremented counter to {0}.", temp); _counter = temp; } } static void SubtractOne() { lock (_lock) { inttemp = _counter; temp--; Thread.Sleep(2000); Console.WriteLine("Decremented counter to {0}.", temp); _counter = temp; } } } Not good, don’t do this, or lock a string or etc.
  • 32. Threading Problems class Program { static int_counter = 0; static object _lock = new object(); static void Main(string[] args) { Parallel.Invoke(AddOne, SubtractOne); Console.WriteLine("Final counter value is {0}.", _counter); } static void AddOne() { lock (_lock) { inttemp = _counter; temp++; Thread.Sleep(2000); Console.WriteLine("Incremented counter to {0}.", temp); _counter = temp; } } static void SubtractOne() { lock (_lock) { inttemp = _counter; temp--; Thread.Sleep(2000); Console.WriteLine("Decremented counter to {0}.", temp); _counter = temp; } } } The best choice for a locking object is a private or protected object defined within the class that controls the shared state.
  • 34. Threading Problems class Program { static int_counter = 0; static object _lock = new object(); constintsleepAmount= 500; static void Main(string[] args) { Thread tAdd= new Thread(AddOne); Thread tSub= new Thread(SubtractOne); tAdd.Start(); tSub.Start(); Console.WriteLine("Final counter value is {0}.", _counter); } static void AddOne() { Monitor.Enter(_lock); try { _counter++; Thread.Sleep(sleepAmount); Console.WriteLine("Incremented counter to {0}.", _counter); } finally { Monitor.Exit(_lock); } } static void SubtractOne() { Monitor.Enter(_lock); try { _counter--; Thread.Sleep(sleepAmount); Console.WriteLine("Decremented counter to {0}.", _counter); } finally { Monitor.Exit(_lock); } } } }
  • 35. Threading Problems class Program { static int_counter = 0; static object _lock = new object(); constintsleepAmount= 500; static void Main(string[] args) { Thread tAdd= new Thread(AddOne); Thread tSub= new Thread(SubtractOne); tAdd.Start(); tSub.Start(); Console.WriteLine("Final counter value is {0}.", _counter); } static void AddOne() { Monitor.Enter(_lock); try { _counter++; Thread.Sleep(sleepAmount); Console.WriteLine("Incremented counter to {0}.", _counter); } finally { Monitor.Exit(_lock); } } static void SubtractOne() { Monitor.Enter(_lock); try { _counter--; Thread.Sleep(sleepAmount); Console.WriteLine("Decremented counter to {0}.", _counter); } finally { Monitor.Exit(_lock); } } } } Monitor Lock
  • 36. Threading Problems class Program { static int_counter = 0; static object _lock = new object(); constintsleepAmount= 500; static void Main(string[] args) { Thread tAdd= new Thread(AddOne); Thread tSub= new Thread(SubtractOne); tAdd.Start(); tSub.Start(); Console.WriteLine("Final counter value is {0}.", _counter); } static void AddOne() { Monitor.Enter(_lock); try { _counter++; Thread.Sleep(sleepAmount); Console.WriteLine("Incremented counter to {0}.", _counter); } finally { Monitor.Exit(_lock); } } static void SubtractOne() { Monitor.Enter(_lock); try { _counter--; Thread.Sleep(sleepAmount); Console.WriteLine("Decremented counter to {0}.", _counter); } finally { Monitor.Exit(_lock); } } } } Acquire Lock
  • 37. Threading Problems class Program { static int_counter = 0; static object _lock = new object(); constintsleepAmount= 500; static void Main(string[] args) { Thread tAdd= new Thread(AddOne); Thread tSub= new Thread(SubtractOne); tAdd.Start(); tSub.Start(); Console.WriteLine("Final counter value is {0}.", _counter); } static void AddOne() { Monitor.Enter(_lock); try { _counter++; Thread.Sleep(sleepAmount); Console.WriteLine("Incremented counter to {0}.", _counter); } finally { Monitor.Exit(_lock); } } static void SubtractOne() { Monitor.Enter(_lock); try { _counter--; Thread.Sleep(sleepAmount); Console.WriteLine("Decremented counter to {0}.", _counter); } finally { Monitor.Exit(_lock); } } } } Release Lock
  • 38. Threading Problems class Program { static int_counter = 0; static object _lock = new object(); constintsleepAmount= 500; static void Main(string[] args) { Thread tAdd= new Thread(AddOne); Thread tSub= new Thread(SubtractOne); tAdd.Start(); tSub.Start(); Console.WriteLine("Final counter value is {0}.", _counter); } static void AddOne() { Monitor.Enter(_lock); try { _counter++; Thread.Sleep(sleepAmount); Console.WriteLine("Incremented counter to {0}.", _counter); } finally { Monitor.Exit(_lock); } } static void SubtractOne() { Monitor.Enter(_lock); try { _counter--; Thread.Sleep(sleepAmount); Console.WriteLine("Decremented counter to {0}.", _counter); } finally { Monitor.Exit(_lock); } } } } Final counter value is 0. Incremented counter to 1. Decremented counter to 0. Press any key to continue . . .
  • 39. Threading Problems class Program { static int_counter = 0; static object _lock = new object(); constintsleepAmount= 500; static void Main(string[] args) { Thread tAdd= new Thread(AddOne); Thread tSub= new Thread(SubtractOne); tAdd.Start(); tSub.Start(); Console.WriteLine("Final counter value is {0}.", _counter); } static void AddOne() { Monitor.Enter(_lock); try { _counter++; Thread.Sleep(sleepAmount); Console.WriteLine("Incremented counter to {0}.", _counter); } finally { Monitor.Exit(_lock); } } static void SubtractOne() { Monitor.Enter(_lock); try { _counter--; Thread.Sleep(sleepAmount); Console.WriteLine("Decremented counter to {0}.", _counter); } finally { Monitor.Exit(_lock); } } } } Final counter value is 0. Incremented counter to 1. Decremented counter to 0. Press any key to continue . . . Why?
  • 40. Threading Problems class Program { static int_counter = 0; static object _lock = new object(); constintsleepAmount= 500; static void Main(string[] args) { Thread tAdd= new Thread(AddOne); Thread tSub= new Thread(SubtractOne); tAdd.Start(); tSub.Start(); tAdd.Join(); tSub.Join(); Console.WriteLine("Final counter value is {0}.", _counter); } static void AddOne() { Monitor.Enter(_lock); try { _counter++; Thread.Sleep(sleepAmount); Console.WriteLine("Incremented counter to {0}.", _counter); } finally { Monitor.Exit(_lock); } } static void SubtractOne() { Monitor.Enter(_lock); try { _counter--; Thread.Sleep(sleepAmount); Console.WriteLine("Decremented counter to {0}.", _counter); } finally { Monitor.Exit(_lock); } } } } Blocks the calling thread until the thread terminates
  • 41. Threading Problems class Program { static int_counter = 0; static object _lock = new object(); constintsleepAmount= 500; static void Main(string[] args) { Thread tAdd= new Thread(AddOne); Thread tSub= new Thread(SubtractOne); tAdd.Start(); tSub.Start(); tAdd.Join(); tSub.Join(); Console.WriteLine("Final counter value is {0}.", _counter); } static void AddOne() { Monitor.Enter(_lock); try { _counter++; Thread.Sleep(sleepAmount); Console.WriteLine("Incremented counter to {0}.", _counter); } finally { Monitor.Exit(_lock); } } static void SubtractOne() { Monitor.Enter(_lock); try { _counter--; Thread.Sleep(sleepAmount); Console.WriteLine("Decremented counter to {0}.", _counter); } finally { Monitor.Exit(_lock); } } } } Incremented counter to 1. Decremented counter to 0. Final counter value is 0. Press any key to continue . . . Blocks the calling thread until the thread terminates
  • 42. Task.Factory varmyTask= Task.Factory.StartNew(() => { return "Hello, world!"; }); Console.WriteLine(myTask.Result);
  • 44. Wait int[] values = null; Task loadDataTask= new Task(() => { Console.WriteLine("Loading data..."); Thread.Sleep(5000); values = Enumerable.Range(1,10).ToArray(); }); loadDataTask.Start(); Console.WriteLine("Data total = {0}", values.Sum());
  • 45. Wait int[] values = null; Task loadDataTask= new Task(() => { Console.WriteLine("Loading data..."); Thread.Sleep(5000); values = Enumerable.Range(1,10).ToArray(); }); loadDataTask.Start(); Console.WriteLine("Data total = {0}", values.Sum()); Will throw ArgumentNullExceptionbecause we are trying to use the array before it has been populated by the parallel task.
  • 46. Wait int[] values = null; Task loadDataTask= new Task(() => { Console.WriteLine("Loading data..."); Thread.Sleep(5000); values = Enumerable.Range(1,10).ToArray(); }); loadDataTask.Start(); Console.WriteLine("Data total = {0}", values.Sum()); Will throw ArgumentNullExceptionbecause we are trying to use the array before it has been populated by the parallel task. int[] values = null; Task loadDataTask= new Task(() => { Console.WriteLine("Loading data..."); Thread.Sleep(5000); values = Enumerable.Range(1,10).ToArray(); }); loadDataTask.Start(); loadDataTask.Wait(); loadDataTask.Dispose(); Console.WriteLine("Data total = {0}", values.Sum()); // Data total = 55
  • 47. int[] values = null; Task loadDataTask= new Task(() => { Console.WriteLine("Loading data..."); Thread.Sleep(5000); values = Enumerable.Range(1,10).ToArray(); }); loadDataTask.Start(); loadDataTask.Wait(); loadDataTask.Dispose(); Console.WriteLine("Data total = {0}", values.Sum()); // Data total = 55 Wait int[] values = null; Task loadDataTask= new Task(() => { Console.WriteLine("Loading data..."); Thread.Sleep(5000); values = Enumerable.Range(1,10).ToArray(); }); loadDataTask.Start(); Console.WriteLine("Data total = {0}", values.Sum()); To fix it, we will now waitfor the task to be done
  • 48. int[] values = null; Task loadDataTask= new Task(() => { Console.WriteLine("Loading data..."); Thread.Sleep(5000); values = Enumerable.Range(1,10).ToArray(); }); loadDataTask.Start(); loadDataTask.Wait(); loadDataTask.Dispose(); Console.WriteLine("Data total = {0}", values.Sum()); Wait int[] values = null; Task loadDataTask= new Task(() => { Console.WriteLine("Loading data..."); Thread.Sleep(5000); values = Enumerable.Range(1,10).ToArray(); }); loadDataTask.Start(); Console.WriteLine("Data total = {0}", values.Sum()); The output will be Data total = 55
  • 49. Tasks Continuation Task continuation = firstTask.ContinueWith(antecedent => { /* functionality */ });