Журнал, когда поток ожидает по прибытии в операторе блокировки - PullRequest
2 голосов
/ 12 октября 2011

Есть ли быстрый способ записать, что поток ожидает блокировки, когда поток достигает

lock(x)
{
  //do work on a collection

}

Если поток 1 приходит к блокировке, а в блоке нет другого потока, не должно быть журнала. Затем, если поток 2 достигает блокировки (x), а поток 1 все еще находится в блоке, должен быть журнал. Идеальное решение не потребовало бы, чтобы переключение на Mutex или Monitor добавило много сложностей. Если есть быстрый и простой способ сделать это с использованием TPL, PLINQ или RX, это было бы здорово.

Ответы [ 3 ]

10 голосов
/ 12 октября 2011

Вы можете удалить сахар из оператора lock и использовать Monitor.TryEnter , чтобы проверить, можно ли получить блокировку без ожидания:

bool lockTaken = false;
var obj = x;
try
{
    Monitor.TryEnter(obj, ref lockTaken);
    if (!lockTaken)
    {
        Log();
        Monitor.Enter(obj, ref lockTaken);
    }
    //do work on a collection
}
finally
{
    if (lockTaken)
    {
        Monitor.Exit(obj);
    }
}
2 голосов
/ 12 октября 2011

Почему вы пытаетесь это сделать? Если это для целей отладки или профилирования, вы можете использовать неуправляемый API профилирования или отладки CLR. Другой идеей было бы статически изменить ваш IL-код после компиляции с помощью такого инструмента, как PostSharp или Afterthought. (Обратите внимание, что Afterthought не может сделать это в его текущей форме, но, поскольку у вас есть источник, вы можете взломать это.)

Я бы порекомендовал вместо этого изменить код. Я бы порекомендовал это вместо синтаксиса dtb:

if (!Monitor.TryEnter(x))
{
    Log();
    Monitor.Enter(x);
}
try
{
    //do work on a collection
}
finally
{
    Monitor.Exit(x);
}
2 голосов
/ 12 октября 2011

Вы не сможете сделать это легко с помощью стандартного оператора lock().Вы можете использовать Monitor.TryEnter(), чтобы попытаться ввести блокировку, а затем зарегистрировать что-либо, если метод возвращает false.

...