This is my code:
Thread _th1, _th2, _th3, _th4;
int _i;
void thMethod()
{
while(_i < 100){
Thread.Sleep((new Random()).Next(1,500));
Application.DoEvents();
Console.WriteLine(_i);
_i++;
}
}
private void button4_Click(object sender, EventArgs e)
{
_th1 = new Thread(new ThreadStart(thMethod));
_th1.Start();
_th2 = new Thread(new ThreadStart(thMethod));
_th2.Start();
_th3 = new Thread(new ThreadStart(thMethod));
_th3.Start();
_th4 = new Thread(new ThreadStart(thMethod));
_th4.Start();
}
What i want to do is,
doing Console.WriteLine from 0 to 99 using multithread,
and the delay is random.
However, my code prints duplicated numbers
well, this is the result.
0
1
2
2
4
5
6
7
8
9
10
10
12
13
14
14
16
16
18
19
20
20
22
22
24
24
26
26
28
28
30
31
32
33
34
35
36
36
38
39
40
40
42
42
44
44
46
46
48
49
50
50
52
52
54
54
56
56
58
58
60
60
62
62
64
65
66
66
68
68
70
70
72
72
74
74
76
76
78
78
80
80
82
82
84
84
86
87
88
88
90
90
92
92
94
94
96
96
98
98
100
101
102
As you see, there are duplicated numbers printed,
and it does not even stop at 99.
So… How to correct this code in order to make it run properly?
====================== Do i have to change like..
void thMethod()
{
while(_i < 100){
Thread.Sleep((new Random()).Next(1,500));
Application.DoEvents();
Interlocked.Increment(ref _i);
Console.WriteLine(_i);
}
}
this?
Although you should be using
Interlocked.Incrementas mentioned by other posts. This isn’t the exact issue you’re having.The reason your numbers go past 100 is because the line you are incrementing the value comes after the Sleep. This causes threads to enter the loop, but by the time they write out the value the value has already changed to be above 100.
For example t1, t2, and t3 enter the loop and wait for 500ms and i is 99. Then t4 exits and increments it to 100, now t1 will print 100, t2 will print 101, t3 will print 102.
Interlocked.Increment wont actually solve the issue because the Thread.Sleep will still cause inconsistencies when the value is actually written out.
To solve the problem you would need to use a thread lock
declare a variable to lock on as you can’t lock on _i as its not a reference type:
This way you will get no duplicates and the value will stop at 99.