Reputation: 969
I have a sample application and wonder if anyone can shine a light on this. When I put a breakpoint on the for loop an step into to the code in the debugger, why does it switch from one thread to another? it does so when running the application at runtime...Please see code below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TPLSample
{
class Program
{
static void Main(string[] args)
{
Management m = new Management();
Task a = new Task(() => m.Operation1());
a.Start();
Task b = new Task(() => m.Operation2());
b.Start();
Console.ReadLine();
}
}
public class Management
{
A a = null;
B b = null;
public void Operation1()
{
a = new A();
}
public void Operation2()
{
b = new B();
}
}
public class A
{ Client a = new Client();
public A()
{
while (true)
{
a.Test("Im AAAAA");
}
}
}
public class B
{
Client a = new Client();
public B()
{
while (true)
{
a.Test("Im BBBBB");
}
}
}
public class Client
{
Object ibj = new Object();
public void Test(string item)
{
lock (ibj)
{
for (int i = 0; i < 200000; i++)
{
Console.WriteLine(item);
}
}
}
}
}
The result for this is a mixture of As and Bs. Isnt the lock suppose to block the thread so that the result will end up in sequence? The same is happening in an application I am writing except that the WHILE loops run forever (each task needs to poll continuosly). Please note that I am starting two tasks because I dont want one WHILE loop to prevent the other from running if the WHILE loop is to run forever. How do I make them go in sequence to that function in CLIENT class?
Upvotes: 2
Views: 565
Reputation: 64218
Each object must have access to the same object to make the lock work. You can do this by making the ibj object static, or passing it into the Client class.
public class Client
{
static Object ibj = new Object();
public void Test(string item)
{
lock (ibj)
{
for (int i = 0; i < 200000; i++)
{
Console.WriteLine(item);
}
}
}
}
Upvotes: 2
Reputation: 62439
This happens because if you trace your object creation tree carefully you will notice that each thread is using a different lock object, thus rendering your lock
statement useless.
Your object creation happens like this:
new A() -> new Client() -> new Object()
/
new Management()
\
new B() -> new Client() -> new Object()
You are using the last two objects on the right as locks, and you can clearly see that they are different objects.
Try to make the lock static:
public class Client
{
static Object ibj = new Object();
...
or otherwise rethink your hierarchy to pass the same lock to both Tasks.
Upvotes: 7