Это версия C # этого вопроса: Последовательно ли std :: mutex?
Вкратце: если несколько потоков блокируют разные объекты, гарантированно ли они видят один и тот же порядок событий в этих разных блокировках?
Вот демонстрация:
internal sealed class Test
{
private readonly object lockerA = new object();
private bool valueA;
private readonly object lockerB = new object();
private bool valueB;
public void RunTest()
{
var taskA = Task.Run(() =>
{
lock (lockerA)
valueA = true;
});
var taskB = Task.Run(() =>
{
lock (lockerB)
valueB = true;
});
var taskC = Task.Run(() =>
{
// Reads A, then B.
bool readA;
lock (lockerA)
readA = valueA;
bool readB;
lock (lockerB)
readB = valueB;
return (readA, readB);
});
var taskD = Task.Run(() =>
{
// Reads B, then A.
bool readB;
lock (lockerB)
readB = valueB;
bool readA;
lock (lockerA)
readA = valueA;
return (readA, readB);
});
Task.WaitAll(taskA, taskB, taskC, taskD);
if (taskC.Result == (readA:true, readB:false) && taskD.Result == (readA:false, readB:true))
{
// Can this happen?
Console.WriteLine("Ordering inconsistency!");
}
}
}
EDIT:
Исправлена ошибка после того, как Мэтью Уотсон показал, что пример терпит неудачу даже при последовательной согласованности.