This code will demonstrate a torn read of a Decimal
:
using System;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
void run()
{
Task.Run((Action) setter);
Task.Run((Action) checker);
Console.WriteLine("Press <ENTER> to stop");
Console.ReadLine();
}
void setter()
{
while (true)
{
d = VALUE1;
d = VALUE2;
}
}
void checker()
{
for (int count = 0;; ++count)
{
var t = d;
if (t != VALUE1 && t != VALUE2)
Console.WriteLine("Value is torn after {0} iterations: {1}", count, t);
}
}
static void Main()
{
new Program().run();
}
Decimal d;
const Decimal VALUE1 = 1m;
const Decimal VALUE2 = 10000000000m;
}
}
It happens faster in a release build than a debug build.
I think the reason that you weren't seeing a torn read in your test code is because you were only changing the value between 0 and 1. It's likely that the bits being changed during your test are all in the same word being used to store the value internally, and accesses to words are atomic.
By changing the value between 1 and 10000000000, we force bits to change in two different words, allowing a torn read to be observed.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…