spaghettiBox
spaghettiBox

Reputation: 103

c# Thread safe property, what about getter without lock?

We have some performance issues and are thinking about to take out some thread safe locks from some heavily used properties. More precisely only from the access modifier getter. The improvement would be that the setter access modifier is not "blocked" anymore if some other thread is making a get on the same property.

-> Of course it has to be ensured that if let's say for an integer type for example the bit value 11110011 which is 243, all bits are written once writing has started. It has to be ensured that never the write thread is unfinished and the get thread becomes some half written bits which results a wrong value. Is it like that?

If so, is that concept usable for all .net built in data types, also string?

See following code example which shows the concept:

    // for properties used just the "Built-In Types"
    // doc: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/built-in-types-table

    private int _ActualValue = 0;
    private readonly object _Lock_ActualValue = new object();
    public int ActualValue
    {
        get
        {
            //lock(_Lock_ActualValue)  <- remove lock for access modifier get ?
            //{
                return _ActualValue;
            //}
        }
        set
        {
            lock (_Lock_ActualValue)
            {
                if((value != _ActualValue) && (value < 1000))
                {
                    Log("_ActualValue", value.ToString());
                    _ActualValue = value;
                }
            }
        }
    }

Upvotes: 2

Views: 2508

Answers (2)

Impurity
Impurity

Reputation: 1122

As a rule of thumb, never put optimization over thread safety. This is considered widely as a bad practice and a direct result of a lot of issues. That being said, no it will never half write a value into an atomic object such as your int ActualValue. Your approach is actually fine if you don't care about full accuracy of the value when you are getting.

EDIT

As a whole, anything that is a multi-step operation in machine code is not atomic. To clarify my answer above, in java the bool, char, byte, sbyte, short, ushort, int, uint, and float types all have atomic writes, thus will not be half written. However, the decimal, double, long, ulong, and DateTime types do not have an atomic write, thus could be partially written.

Upvotes: 3

Vibeeshan Mahadeva
Vibeeshan Mahadeva

Reputation: 7238

private ReaderWriterLockSlim lockObj = new ReaderWriterLockSlim();

private int _ActualValue = 0;
public int ActualValue
{
    get
    {
        lockObj.EnterReadLock();

        try
        {
            return _ActualValue;
        }
        finally
        {
            lockObj.ExitReadLock();
        }
    }
    set
    {
        lockObj.EnterWriteLock();
        try
        {

            if((value != _ActualValue) && (value < 1000))
            {
                Log("_ActualValue", value.ToString());
                _ActualValue = value;
            }
        }
        finally
        {
            lockObj.ExitWriteLock();
        }
    }
}

Upvotes: 0

Related Questions