Another answer regarding reproducing torn thread reads of decimal values in c# shows that this code successfully does reproduce a torn thread. I am able to successfully reproduce that behavior in my environment as well. However, if I change Decimal d;
to public static Decimal d { get; set; }
the torn thread is not reproduced. Why is that?
Separately, I am using a series of lock statements to prevent torn threads. The only way I will feel comfortable that I have permanently prevented torn threads is to be able to generate torn threads on purpose, apply lock statements in the same method I am using in production bound code, and see that the locks successfully do what they are supposed to without significant performance impact. Is there a better way to purposefully generate torn threads?
If changing to public static
is enough to cause a timing difference in my environment, then I'm fearful that lock
statements could be causing the same timing differences as well rather than actually locking what I'm intending to be locked. Is there a way to create a better test rig?
Edit: My environment is - Target Framework netcoreapp2.0, Windows 10 64-bit, Intel Core i7-4712HQ. Using different Platform targets of Any, x86, or x64 does not impact the test results in my environment. Neither does building with or without "Optimize code" enabled.
using System;
using System.Threading.Tasks;
namespace ConsoleApp2
{
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();
}
//Torn thread is not reproduced if this line changed to:
//public static Decimal d { get; set; }
Decimal d;
const Decimal VALUE1 = 1m;
const Decimal VALUE2 = 10000000000m;
}
}