One of my classes has a property of type Guid. This property can read and written simultaneously by more than one thread. I'm under the impression that reads and writes to a Guid are NOT atomic, therefore I should lock them.
I've chosen to do it like this:
public Guid TestKey
{
get
{
lock (_testKeyLock)
{
return _testKey;
}
}
set
{
lock (_testKeyLock)
{
_testKey = value;
}
}
}
(Inside my class, all access to the Guid is also done through that property rather than accessing _testKey directly.)
I have two questions:
(1) Is it really necessary to lock the Guid like that to prevent torn reads? (I'm pretty sure it is.)
(2) Is that a reasonable way to do the locking? Or do I need to do it like the following:
get
{
Guid result;
lock (_testKeyLock)
{
result = _testKey;
}
return result;
}
[EDIT] This article does confirm that Guids will suffer from torn reads: http://msdn.microsoft.com/en-us/magazine/jj863136.aspx
1: yes; to protect from torn values if you have one thread reading and one writing; Guid
is not guaranteed to be atomic
2: "like the following": they are effectively the same; at the IL level you cannot ret
from a try
/catch
block, so the compiler implements your first example by introducing a local variable, just like in your second example.
Another approach might be to box it; a reference is atomic:
object boxedTestKey;
public Guid TestKey
{
get { return (Guid)boxedTestKey; }
set { boxedTestKey = value; }
}
No locking required, but a small overhead from the box.
1) Is it really necessary to lock the Guid like that to prevent torn reads? (I'm pretty sure it is.)
Yes it is.
2) Is that a reasonable way to do the locking?
Again: Yes.
If there had existed an Interlocked
method for Guid
then that would have been better (faster).
For double
(another non-atomic struct) there is support from Interlocked
and for references it is not needed.
So as a pattern this is only required for larger structs that are not supported by Interlocked
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With