Although I have read already a lot through docs and forums I am still not clear about data caching and visibility of data shared among threads.
I am clear about updating values shared by different threads using lock statement.
As an example:
public class Foo
{
object locker = new object();
int someValue;
public void SetValue (int value)
{
lock (locker)
{
someValue = value;
}
}
public int GetValue()
{
int value ;
lock(locker)
{
value = someValue;
}
return value;
}
}
But now lets get a little bit deeper, where my problem is.
Think of a class named Person which is predefined and cannot be modified (for example it is coming from another assembly)
A class instance shall be passed between two threads.
public class Person
{
public string Name { get; }
public string SirName { get; }
public uint Age { get; }
public bool EntryValid { get; }
public Person(string name, string sirName, uint age)
{
Name = name;
SirName = sirName;
Age = age;
EntryValid = true;
}
public Person()
{
EntryValid = false;
}
}
public class FoundResult
{
private object locker;
private Person person;
private bool result;
public FoundResult ()
{
locker = new object();
// Is lock required here?
result = false;
}
// Called from Thread No 1
public void PlaceResult(Person person)
{
lock (locker)
{
this.person = person; // This may be extended by an additional Clone();
result = true;
}
}
// Called from Thread No 2
public bool HasResult()
{
bool result;
lock (locker)
{
result = this.result;
}
return result;
}
// Called from Thread No 2
public Person GetResult()
{
Person person;
lock (locker)
{
person = this.person; // This may be extended by an additional Clone();
result = false;
}
return person;
}
}
To reduce overloading the example I assume that the threads will be signaled properly so that they will know when to access the methods. Then it will goes like this::
Thread no 1 is going to be asked to search for a person (for instance by a list which is held into the threads space) and places the result by calling PlaceResult. The thread will be going to signal Thread no. 2 which is going to call GetResult().
The question is now about the visibility of the data stored in person instance. Does lock guarantee that the values (name, age etc.) in person are passed from thread no 1 to no 2?
Or is it still possible that both threads only work on their caches or registers and thread no 2 reads sometimes the same "old" data?
And if so, how do I manage that the data are properly passed without touching the Person class itself?