have another confusion about locking in C#.
The problem is sharing a state among diffrent threads.
Following scenario:
A thread processes a state machine. This machine, for example, counts up a value with delay. The machine thread reads this value and increments. Other threads shall now be able to read this count value. Actually I have more values than just a a single count, so I prepared a class which holds the shared values. This looks like this:
IStatus
is a suitable private interface. Summaries are removed since not in English.
public class Status : ICloneable, IStatus
{
private object locker;
public bool Run { get; private set; }
public uint SecondRemain { get; private set; }
// ... and some more value types
public Status()
{
locker = new object();
}
void IStatus.SetRun(bool enable)
{
lock (locker)
{
Run = enable;
}
}
void IStatus.SetSecondRemain (uint value)
{
lock (locker)
{
SecondRemain = value;
}
}
// ... and some more set of value types
public object Clone()
{
object copy;
lock (locker)
{
copy = MemberwiseClone();
// Since it is a "new" object, we decouple the lock
((Status)copy).locker = new object();
}
return copy;
}
In main class where the state machine and its thread lives in:
private Status shared;
// Shall be accessible by any thread at any time
public Status GetStatus()
{
// Clones thread-safe, fenced by locker
return (Status) shared.Clone();
}
// Will be accessed only by inner thread
private void AnyMethodCalledStateMachineThread()
{
// Get the current remaining second value.
// No fence here ??
uint value = shared.SecondRemain;
// fences by locker
((IStatus) shared).SetSecondRemain (value++);
}
What we see now is, only the inner thread will read and write to some values. This thread will read what it has previously written. To ensure other threads can read this, it is locked.
External threads can only get a full copy by lock statement.
But does internal thread itself needs lock, too, when reading single properties or do I have to put lock around these properties (with extra field)?
EDIT
This is the requested sort of code which runs the thread
var thread;
private void Start()
{
thread = new Thread(new ThreadStart(ProducerMain));
thread.Start();
}
// Example, no real code
private void ProducerMain()
{
while ( ...)
{
Thread.Sleep(1000);
AnyMethodCalledStateMachineThread();
}
}