I am implementing a class that will be used concurrently from multiple threads. Most of the properties get and set primitive types which can be handled properly by the Interlocked class. The class includes a Guid property. This is not as straight-forward to implement in a thread-safe manner. Is this how you would implement the property? Thanks in advance.
private Byte[] _activityId;
public Guid ActivityId
{
get { return new Guid(this._activityId); }
set
{
Byte[] bytes = value.ToByteArray();
Interlocked.Exchange(ref this._activityId, bytes);
}
}
UPDATE: So the only proposed solution up to this point doesn't include the use of any "Threading" classes or constructs. So I am going to pose the question that I've already posed in comments:
My understanding is that reference/primitive values types assignments are atomic however Interlocked will guarantee the change is propagated to all threads. If we could simply just assign the value, why does Interlocked expose APIs to exchange reference types and primitive values?
You can get cheaper atomic assignment by creating your own box class:
class Box<T> where T : struct {
public readonly T Value;
public Box(T value) { Value = value; }
}
By storing a reference to the (immutable) Box
instance instead of storing the value directly, all operations on the field will be atomic.
private Box<Guid> _activityId;
public Guid ActivityId {
get { return this._activityId.Value; }
set { this._activityId = new Box<Guid>(value); }
}
This way, the non-atomic struct copy operations happen in new Box<Guid>(value)
and in the .Value
access. Since they don't involve the field, they won't cause trouble.
This should be much faster than using byte arrays, and a little bit faster than native boxing with a cast. (disclaimer: I haven't measured)
I think you could use the other overload of Interlocked.Exchange
:
private volatile object _activityId; // Yes, object :)
public Guid ActivityId {
get { return (Guid)_activityId; }
set { _activityId = value; }
}
This works because the Guid
is now boxed, and the assignment of reference types is atomic.
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