Reputation: 191
I am building a program in C# with 2 Threads that use the same Object. the first Thread updating the Object value and the second Thread printing it to the GUI.
I am searching for the most correct
or clean
way to implement the locking mechanism between the Threads.
an example of the implementation I have in my program (not the actual program):
namespace Test___Console
{
public class Custom
{
public static object lockinObject = new object();
public string name;
public int value;
public Custom(string name)
{
this.name = name;
}
}
public class Program
{
public static object lockinObject = new object();
static Thread firstThread;
static Thread secondThread;
static public Custom someData;
static void Main(string[] args)
{
someData = new Custom("first");
firstThread = new Thread(FirstThreadFunctions);
secondThread = new Thread(SecondThreadFunctions);
firstThread.Start();
secondThread.Start();
do
{
} while (true);
}
static void FirstThreadFunctions()
{
Random rnd = new Random();
do
{
someData.value = rnd.Next();
Thread.Sleep(1000);
} while (true);
}
static void SecondThreadFunctions()
{
do
{
Console.WriteLine(someData.value.ToString());
Thread.Sleep(1000);
} while (true);
}
}
}
I thought of 3 ways to lock the someData object
1.add get set with locking object to the someData object.
2.add get set with locking object to the Custom Class variables.
3.encapsulate all the code segments that use the same data object with locking statements(my least favorite method).
I don't have a lot of programming experience so I ask you what is the "correct" or "cleanest" way to deal with this problem.
Thank you
Upvotes: 2
Views: 1044
Reputation: 26362
You want to limit your blocking code as much as possible. Let's take your case for example.
Effectively, what you are trying to do is lock an object and prevent it from reading while it is written. No need to lock it while reading from other readers.
ReaderWriterLockslim to the resue. Then in your Custom
class
public class Custom
{
private ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim();
private int currvalue;
public int value {
get {
cacheLock.EnterReadLock();
var retValue = currvalue;
cacheLock.ExitReadLock();
return retValue;
}
set {
cacheLock.EnterWriteLock();
this.currvalue = value;
cacheLock.ExitWriteLock();
}
}
}
This way, you are limiting concurrency only to the current object that needs to be thread safe, the lock is being applied very closely to the data so that no deadlocks will be easily introduced and only for the writting action.
Upvotes: 2