Synchronization of property access with Class Lock - c#

Please consider the following code
public class DataModel
{
public int a { get; set; }
}
public static class StaticAccess
{
private static _Data = new DataModel();
private static DataModel Data {
lock(_Data) {
return _Data;
}
}
}
Will an access to property a such us StaticAccess.Data.a = 3; will lock for the entire property value assignment or just for the _Data static field reference retrieval?
In other words, can I use the above implementation to synchronize the access to the properties of the underlying data model or do I have to implement the lock in every single property of it?
e.g.
public class DataModel
{
private int _a;
public int a {
get {
lock(this) {
return _a;
}
}
set {
lock(this) {
_a = value;
}
}
}
Thanks in advance.

The code in your first example will synchronize access to the instance of DataModel in the StaticAccess class (i.e.: to the _Data field), not to members of the instance of DataModel itself. For that you need your second example.
Side note: Avoid locking on this, and use a dedicated object to lock on, as you don't know who else might lock on the instance. Use something like
public class DataModel
{
private readonly object _lock= new object();
private int _a;
public int a {
get {
lock(_lock) {
return _a;
}
}
set {
lock(_lock) {
_a = value;
}
}
}
Edit based on comments:
The Data property of StaticAccess returns the instance of DataModel. So only thread at a time can obtain the reference to that instance. The goal, however, is to synchronize access to DataModel.a. Since access to DataModel.a is not synchronized any code that tries to either read or write to DataModel.a is not synchronized meaning that multiple threads accessing StaticAccess.Data.a is not synchronized:
void ThreadProc1()
{
// (might) block on "get StaticAccess.Data"
// will not block on "DataModel.a = 20"
StaticAccess.Data.a = 20;
}
void ThreadProc2()
{
// (might) block on "StaticAccess.Data"
// will not block on "DataModel.a = 10"
StaticAccess.Data.a = 10;
// (might) block on "StaticAccess.Data"
// will not block on "DataModel.a"
// "StaticAccess.Data.a" might be 10 or 20;
Console.WriteLine(StaticAccess.Data.a);
}

Related

cache the variable in constructor C#

i have one class with constractor like this
public class product_new : NK.Objects._product_new
{
private int Count_Per_Page;
public product_new(int count_per_page)
{
this.Count_Per_Page = count_per_page;
}
public int CountOP///////count of pages
{
get
{
return number_of_pages(Count_Per_Page);
}
}
as you see the CountOP is return a int value and it is connect to sql database to return this value.
private int number_of_pages(int tedad_per_pages)
{
return Q.Get_Back_Number_Of_Pages(
tedad_per_pages,
tbl_name,
"",
new Queries.Cmd_Parameters());
}
in several time if create object from this class the CountOP is not changed but the function number_of_pages is released and connect to the sql database.
how can i cache this variable?
Try using static Dictionary<int, int> - one dictionary for all the instances:
public class product_new : NK.Objects._product_new {
// Simplest, but not thread safe; use ConcurrentDictionary for thread safe version
private static Dictionary<int, int> s_KnownAnswers = new Dictionary<int, int>();
// Lazy: do not execute expensive operation eagerly: in the constructor;
// but lazyly: in the property where we have to perform it
public int CountOP {
get {
int result = 0;
// do we know the answer? If yes, then just return it
if (s_KnownAnswers.TryGetValue(Count_Per_Page, out result))
return result;
// if no, ask RDMBS
result = number_of_pages(Count_Per_Page);
// and store the result as known answer
s_KnownAnswers.Add(Count_Per_Page, result);
return result;
}
}
...
}
Introduce a private backing-field that holds the value and initialize its value within your constructor. Now you can return the variables value within your getter instead of hitting the database every time you call the getter.
public class product_new : NK.Objects._product_new
{
private int Count_Per_Page;
private readonly int _CountOP;
public product_new(int count_per_page)
{
this.Count_Per_Page = count_per_page;
this._CountOP = number_of_pages(count_per_page);
}
public int CountOP///////count of pages
{
get
{
return this._CountOP;
}
}
Apart from this I strongly suggest to have a look at Mircrsofts naming-conventions.
Change to use a backed property:
private int _npages = -1;
public int CountOP///////count of pages
{
get
{
if(_npages == -1)
_npages = number_of_pages(Count_Per_Page);
return _npages;
}
}

Thread-safety work with static field

Consider the code:
class InnerClass
{
public int State { get; set; }
public bool Equals(InnerClass other) => State == other.State;
public override int GetHashCode() => State;
public override string ToString() => State.ToString();
}
class TestClass
{
private static InnerClass _innerClass;
private static readonly object _syncObject = new object();
public InnerClass Get()
{
lock (_syncObject)
{
return _innerClass;
}
}
public void Set(InnerClass innerClass)
{
lock (_syncObject)
{
_innerClass = innerClass;
}
}
}
[Fact]
public void TestClassTest()
{
var firstInnerClass = new InnerClass() {State = 1};
var secondInnerClass = new InnerClass() {State = 2};
Assert.NotEqual(firstInnerClass, secondInnerClass);
for (int i = 0; i < 100000; i++)
{
var testClass = new TestClass();
testClass.Set(firstInnerClass);
var currentInnerClass = testClass.Get();
Task.Run(() => testClass.Set(secondInnerClass));
Assert.Equal(firstInnerClass, currentInnerClass);
}
}
It does not work. I understand that it is related to _innerClass field. Looks like currentInnerClass pointer can be replaced later.
But why is the next code work fine then?
class TestClass
{
private static InnerClass _innerClass;
public InnerClass Get()
{
return Interlocked.CompareExchange(ref _innerClass, _innerClass, _innerClass);
}
public void Set(InnerClass innerClass)
{
Interlocked.CompareExchange(ref _innerClass, innerClass, null);
}
}
So there are two questions:
How exactly Interlocked works with memory so that it can work fine?
How can I change the first code (with lock operator) to make it ok? Maybe MemoryBarrier can help me? I am not sure...
So lets look at what you are doing here in your loop:
// Here you are creating a new TestClass. Should be whole new state, right
//Maybe not...
var testClass = new TestClass();
// Here we set the field to firstInnerClass
testClass.Set(firstInnerClass);
// Here we get the field value. Should be firstInnerClass always, right? Maybe...
var currentInnerClass = testClass.Get();
// Here we create a task to run on another thread.
// This will asynchronously update the state.
// Might take a while though...
Task.Run(() => testClass.Set(secondInnerClass));
// Here we assert that the state we read is what we set
Assert.Equal(firstInnerClass, currentInnerClass);
So far, so good. We write a value, we read a value, we asynchronously kick off a change to that value, and then we confirm that what we read is what we wrote.
The problem lies here:
private static InnerClass _innerClass;
static here means that the field is associated with the type, not the instance. It is shared across all instances of the class. So what is happening is that on some iteration N, the async Task from iteration N-1 is taking long enough to complete that it performs it's update between the write and the read. So the read gets secondInnerClass, not firstInnerClass. The fact that you are creating a new TestClass is irrelevant- the content fields of that class are static and so shared with every other copy.
If you change TestClass to the following, the error should disappear:
class TestClass
{
private InnerClass _innerClass;
private readonly object _syncObject = new object();
public InnerClass Get()
{
lock (_syncObject)
{
return _innerClass;
}
}
public void Set(InnerClass innerClass)
{
lock (_syncObject)
{
_innerClass = innerClass;
}
}
}

Is the following get / reset pair thread safe in C#?

Please look at the following code:
public sealed class Foo<T> : IDisposable
where T : IDisposable, new()
{
public T Bar
{
get { return _bar; }
}
public void Reset()
{
var oldBar = _bar;
using (oldBar)
{
_bar = new T();
}
}
public void Dispose()
{
// TODO:
}
private T _bar = new T();
}
Consider multithreaded environment. Bar getter and Reset method are being called from multiple threads. Is it guaranteed that client would never get a disposed T object via Bar property? Foo object is guaranteed not to be disposed at that moment. If not, how to get it right? I want to use low-lock techniques if possible.
Thank you in advance.
UPDATE
Thank you all guys for the help. The question need to be clarified. I want
Foo to manage Bar state;
to be sure that clients will not use disposed T object.
It seems that it is impossible with the code provided before. Here is the code that reflects my needs:
public sealed class Foo<T> : IDisposable
where T : class, IDisposable, new()
{
public bool TryExecute(Action<T> action)
{
lock (_sync)
{
if (_bar == null)
{
return false;
}
action(_bar);
return true;
}
}
public void Reset()
{
lock (_sync)
{
if (_bar == null)
{
throw new ObjectDisposedException(string.Empty);
}
Reset(new T());
}
}
public void Dispose()
{
lock (_sync)
{
if (_bar != null)
{
Reset(null);
}
}
}
private void Reset(T newBar)
{
var oldBar = _bar;
using (oldBar)
{
_bar = newBar;
}
}
private T _bar = new T();
private readonly object _sync = new object();
}
I beleive it is thread safe this time.
You can't get all of the requirements, but at least you can make Reset itself thread-safe without locks. As it is, it can fail because multiple concurrent calls could try to dispose the same object.
You can't prevent clients from storing a reference to a previous T instance.
What you can do, is ensure that only one Reset call can change the stored value at a time, using Interlocked.CompareExchange. This would also allow one of the calls to dispose the old value. The original code would fail because all concurrent calls could attempt to dispose the same old value. With CompareExchange we can swap new and old values atomically :
public void Reset()
{
var originalValue=_bar;
var replaced=Interlocked.CompareExchange(ref _bar,new T(),originalValue);
if(replaced!=_bar)
{
//We got to replace the value,
//we could dispose it safely if we wanted to
if (replaced!=null)
{
replaced.Dispose();
}
}
}
The comparison to oldValue means that even if two threads execute Reset concurrently, only one of them will be allowed to assign to _bar and be able to dispose the old value. The other will see that _bar has a new value.
This doesn't solve the problem of multiple temporary objects and anyway, we don't want to dispose.
It would be easier if Reset accepted a parameter with the replacement value so it didn't have to create the new objects itself.
public void Reset(T newValue)
{
var originalValue=_bar;
var replaced=Interlocked.CompareExchange(ref _bar,newValue,originalValue);
...
}
I would say use _bar variable via Bar property only, do not use it directly. Put a lock on set property on Bar. Code as follows:
public sealed class Foo<T> : IDisposable
where T : IDisposable, new()
{
private readOnly object key;
public Foo(){
key = new Object();
this.Bar = new T();
}
public T Bar
{
get { return _bar; }
private set {
lock(key){
_bar = value;
}
}
}
public void Reset()
{
var oldBar = _bar;
this.Bar = new T();
}
public void Dispose()
{
this.Bar = null;
}
private T _bar;
}

How to ensure a certain method doesn't get executed if some other method is running?

Let's say I have two methods -
getCurrentValue(int valueID)
updateValues(int changedComponentID)
These two methods are called on the same object independently by separate threads.
getCurrentValue() simply does a database look-up for the current valueID.
"Values" change if their corresponding components change. The updateValues()method updates those values that are dependent upon the component that just changed, i.e. changedComponentID. This is a database operation and takes time.
While this update operation is going on, I do not want to return a stale value by doing a lookup from the database, but I want to wait till the update method has completed. At the same time, I don't want two update operations to happen simultaneously or an update to happen when a read is going on.
So, I'm thinking of doing it this way -
[MethodImpl(MethodImplOptions.Synchronized)]
public int getCurrentValue(int valueID)
{
while(updateOperationIsGoingOn)
{
// do nothing
}
readOperationIsGoingOn = true;
value = // read value from DB
readOperationIsGoingOn = false;
return value;
}
[MethodImpl(MethodImplOptions.Synchronized)]
public void updateValues(int componentID)
{
while(readOperationIsGoingOn)
{
// do nothing
}
updateOperationIsGoingOn = true;
// update values in DB
updateOperationIsGoingOn = false;
}
I'm not sure whether this is a correct way of doing it. Any suggestions? Thanks.
That's not the correct way. Like this you are doing an "active wait", effectively blocking your CPU.
You should use a lock instead:
static object _syncRoot = new object();
public int getCurrentValue(int valueID)
{
lock(_syncRoot)
{
value = // read value from DB
}
}
public void updateValues(int componentID)
{
lock(_syncRoot)
{
// update values in DB
}
}
Create a static object outside of both of these methods. Then use a lock statement on that object; when one method is accessing the protected code, the other method will wait for the lock to release.
private static object _lockObj = new object();
public int getCurrentValue(int valueID)
{
object value;
lock(_lockObj)
{
value = // read value from DB
}
return value;
}
public void updateValues(int componentID)
{
lock(_lockObj)
{
// update values in DB
}
}
private static readonly object _lock = new object();
public int getCurrentValue(int valueID)
{
try
{
Monitor.Enter(_lock);
value = // read value from DB
return value;
}
finally
{
Monitor.Exit(_lock);
}
}
public void updateValues(int componentID)
{
try
{
Monitor.Enter(_lock);
// update values in DB
}
finally
{
Monitor.Exit(_lock);
}
}

How to implement Lazy loading with PostSharp?

I would like to implement lazy loading on properties with PostSharp.
To make it short, instead of writing
SomeType _field = null;
private SomeType Field
{
get
{
if (_field == null)
{
_field = LongOperation();
}
return _field;
}
}
I would like to write
[LazyLoadAspect]
private object Field
{
get
{
return LongOperation();
}
}
So, I identify that I need to emit some code in the class to generate the backing field, as well as inside the getter method in order to implement the test.
With PostSharp, I was considering overriding CompileTimeInitialize, but I am missing the knowledge to get a handle over the compiled code.
EDIT:
The question can be extended to any parameterless method like:
SomeType _lazyLoadedField = null;
SomeType LazyLoadableMethod ()
{
if(_lazyLoadedField ==null)
{
// Long operations code...
_lazyLoadedField = someType;
}
return _lazyLoadedField ;
}
would become
[LazyLoad]
SomeType LazyLoadableMethod ()
{
// Long operations code...
return someType;
}
After our comments, I think I know what you want now.
[Serializable]
public class LazyLoadGetter : LocationInterceptionAspect, IInstanceScopedAspect
{
private object backing;
public override void OnGetValue(LocationInterceptionArgs args)
{
if (backing == null)
{
args.ProceedGetValue();
backing = args.Value;
}
args.Value = backing;
}
public object CreateInstance(AdviceArgs adviceArgs)
{
return this.MemberwiseClone();
}
public void RuntimeInitializeInstance()
{
}
}
Test code
public class test
{
[LazyLoadGetter]
public int MyProperty { get { return LongOperation(); } }
}
Thanks to DustinDavis's answer and comments, I could work on my own implementation, and I just wanted here to share it to help other people.
The main differences from the original answer are:
Implement the suggested "only run the operation once" (purpose of the lock)
Made the initialization status of the backing field more reliable by passing this responsibility to a boolean.
Here is the code:
[Serializable]
public class LazyLoadAttribute : LocationInterceptionAspect, IInstanceScopedAspect
{
// Concurrent accesses management
private readonly object _locker = new object();
// the backing field where the loaded value is stored the first time.
private object _backingField;
// More reliable than checking _backingField for null as the result of the loading could be null.
private bool _hasBeenLoaded = false;
public override void OnGetValue(LocationInterceptionArgs args)
{
if (_hasBeenLoaded)
{
// Job already done
args.Value = _backingField;
return;
}
lock (_locker)
{
// Once the lock passed, we must check if the aspect has been loaded meanwhile or not.
if (_hasBeenLoaded)
{
args.Value = _backingField;
return;
}
// First call to the getter => need to load it.
args.ProceedGetValue();
// Indicate that we Loaded it
_hasBeenLoaded = true;
// store the result.
_backingField = args.Value;
}
}
public object CreateInstance(AdviceArgs adviceArgs)
{
return MemberwiseClone();
}
public void RuntimeInitializeInstance() { }
}
I think the requirement cannot be accurately described as 'lazy loading', but is a special case of a more general caching aspect with in-AppDomain storage but without eviction. A general caching aspect would be able to handle method parameters.

Categories