使Guid属性线程安全

Mat*_*son 5 c# multithreading

我的一个类有一个Guid类型的属性.此属性可以由多个线程同时读取和写入.我的印象是对Guid的读写不是原子的,因此我应该锁定它们.

我选择这样做:

public Guid TestKey
{
    get
    {
        lock (_testKeyLock)
        {
            return _testKey;
        }
    }

    set
    {
        lock (_testKeyLock)
        {
            _testKey = value;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

(在我的课程中,对Guid的所有访问也是通过该属性完成的,而不是直接访问_testKey.)

我有两个问题:

(1)是否真的有必要像这样锁定Guid以防止撕裂读数?(我很确定它是.)

(2)这是一种合理的锁定方式吗?或者我需要像下面这样做:

get
{
    Guid result;

    lock (_testKeyLock)
    {
        result = _testKey;
    }

    return result;
}
Run Code Online (Sandbox Code Playgroud)

[编辑]本文确认Guids将遭受撕裂的读取:http://msdn.microsoft.com/en-us/magazine/jj863136.aspx

Mar*_*ell 8

1:是的; 如果你有一个线程读数和一个写入,以防止撕裂的价值; Guid不保证是原子的

2:"喜欢以下":它们实际上是一样的; 在IL级别,您不能 rettry/ catchblock,因此编译器通过引入局部变量来实现您的第一个示例,就像在第二个示例中一样.

另一种方法可能就是把它装箱; 引用原子的:

object boxedTestKey;
public Guid TestKey
{
    get { return (Guid)boxedTestKey; }
    set { boxedTestKey = value; }
}
Run Code Online (Sandbox Code Playgroud)

不需要锁定,但是盒子的开销很小.


Hen*_*man 4

1)真的有必要像这样锁定Guid以防止撕裂读取吗?(我很确定是这样。)

是的。

2)这是一种合理的锁定方式吗?

再次:是的。

如果存在一种Interlocked方法,Guid那就会更好(更快)。

对于double(另一个非原子结构),Interlocked不需要引用的支持和引用。

因此,作为一种模式,只有Interlocked.