Proposal: Implicit volatile backing field for volatile Auto Implemented Properties #3006
Replies: 6 comments
-
Is volatile enough? In thread safe design, many other constructions like locks, CompareExchange are used. And also, Many thread safe operations requires reading a field only once. I think the language team is considering volatile not common enough. |
Beta Was this translation helpful? Give feedback.
-
Depends. Yes, Interlocked.CompareExchange, or any sort of Mutex are preferred to serialize access to any resource, but there are scenarios where volatile is enough, consider the following: public bool Active { get; private set; } //volatile
readonly object ControlMutex;
public bool Start()
{
lock (ControlMutex)
{
if (Active) return false;
//...
Active = true;
return true;
}
} Here, all writes to Active would happen in a synchronized context, but reads can happen from code the writer has no control over, and thus some form of memory barrier needs to be in place to make sure the read does not get optimized away, and for that volatile is enough. Other way would be int i = 0;
public bool Active
{
get => Interlocked.CompareExchange(ref i, 1, 1) == 1;
set => Interlocked.CompareExchange(ref i, value ? 1 : 0, value ? 0 : 1);
} But volatile is cleaner, and enough, or at least that's what I think, feel free to prove me wrong. |
Beta Was this translation helpful? Give feedback.
-
The compiler does not magically optimise away reads because a field is not volatile; it cannot do that |
Beta Was this translation helpful? Give feedback.
-
Yes it can, and it does. Run Debug, then Release. using System;
using System.Threading;
namespace ConsoleApp1
{
class Program
{
public bool Flag { get; set; }
public void VolatilityTest()
{
Thread.Sleep(1000);
Flag = true;
}
static void Main(string[] args)
{
Program p = new Program();
var t = new Thread(p.VolatilityTest);
t.Start();
bool work = false;
while (!p.Flag)
{
work = !work; // fake work simulation
}
t.Join();
}
}
} |
Beta Was this translation helpful? Give feedback.
-
Sharing mutable data across threads is really really difficult to write correctly. If you're using |
Beta Was this translation helpful? Give feedback.
-
Oh, my bad. Still, I think this is unusual enough that just manually writing out the field is best. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Should expand to:
Rationale:
In a multi-threaded scenario, public properties should be volatile to prevent compiler optimizing away reads*, and having an explicit backing field adds clutter to the code, so it makes sense to "pass" the volatile keyword down to the backing field on an Auto Implemented Property.
*See StackOverflow.com for an example.
Beta Was this translation helpful? Give feedback.
All reactions