C# Locking, Properties & Permissions

I've been using lock on value type properties when multi-threaded access is required. Also, I've been meaning to become more diligent about applying proper access modifiers, especially in my library code that is starting to become useful in multiple projects. I've written some code and would like to request comments on the various strategies in it for properties and locking the member variables they wrap. Thanks.

using System;

public class Program
{
    static void Main(string[] args)
    {
        SomeValueType svt = new SomeValueType();
        SomeReferenceType srt = new SomeReferenceType();        
        PermissionsAndLocking p = new PermissionsAndLocking(5, svt, srt);

        //Invalid.
        //p.X = 6;

        //Invalid
        //p.Svt = new SomeValueType();
        //Invalid
        //p.Svt.X = 1;
        //Valid, but changes a copy of p.Svt because Svt is a value type.
        SomeValueType svt2 = p.Svt;
        svt2.X = 7;

        //Invalid
        //p.Srt = new SomeReferenceType();
        //Valid, change the member data of p.Srt.
        p.Srt.X = 8;        
        SomeReferenceType srt2 = p.Srt;
        srt2.X = 9;

        Console.WriteLine("Press the any key.");
        Console.Read();
    }
}

public class PermissionsAndLocking
{
    //_x cannot be changed outside the class.
    //_x cannot be changed "at the same time" it is being accessed???
    private readonly object _xLock = new object();
    private int _x;
    public int X
    {
        get
        {
            lock (_xLock)
            {
                return _x;
            }
        }
        private set
        {
            lock (_xLock)
            {
                _x = value;
            }
        }
    }

    //_svt and its members cannot be assigned to outside the class.
    //_svt cannot be changed "at the same time as" it is being accessed.
    private readonly object _svtLock = new object();
    private SomeValueType _svt;
    public SomeValueType Svt
    {
        get
        {
            lock (_svtLock)
            {
                return _svt;
            }
        }
        private set
        {
            lock (_svtLock)
            {
                _svt = value;
            }
        }
    }

    //private on set works for = but member data can still be manipulated...
    //Locking isn't complete because the reference is returned and can be accessed at a later time???
    private readonly object _srtLock = new object();
    private SomeReferenceType _srt;
    public SomeReferenceType Srt
    {
        get
        {
            lock (_srtLock)
            {
                return _srt;
            }
        }
        private set
        {
            lock (_srtLock)
            {
                _srt = value;
            }
        }
    }

    public PermissionsAndLocking(int x, SomeValueType svt, SomeReferenceType srt)
    {
        _x = x;
        _svt = svt;
        _srt = srt;
    }
}

public struct SomeValueType
{
    public int X;
}

public class SomeReferenceType
{
    public int X;
}

You need to read about multi-threading and concurrency. Locking is about protecting invariants whilst they are invalid, ie, while an invariant is invalid, prevent concurrent access to the shared memory that the invariant is dependant upon. The first step is to understand what invariant your code routine has, and secondly, within which block of code is the invariant invalid.

For example, a property getter has no intrinsic need to be synchronized with a lock. It only reads the property value. What invariant is invalid while this read is going on ? An operation that reads the variable, increments it, and then writes the incremented value back to the property might need to be locked, but locking the individual getter and setter would be totally inadequate. The entire operataion, including the read and the write, would have to be inside the protected block.


  • You should always lock a static object, so you should mark _svtLock as static in order for the lock to have an effect.
  • _x cannot be changed outside the class. True. It must be changed via X .
  • If you implement lock correctly ( see 1), then _x can't be changed at the time it's accessed.
  • 链接地址: http://www.djcxy.com/p/57924.html

    上一篇: 从蓝牙接收字符串后使用线程更新标签

    下一篇: C#锁定,属性和权限