Недавно я пытался определить, какая функция удерживает блокировку, и обнаружил, что следующее очень полезно и не встречалось ранее нигде. Я разместил его здесь как ответ на тот случай, если другие найдут его полезным.
Многие другие решения, опубликованные ранее, требуют написания нового класса, а затем преобразования всех блокировок (бла) в BetterLock (бла), что является большой работой для отладки и которую вы, возможно, не захотите в рабочей / поставленной версии ваш код. Другим требовалось подключить отладчик, который изменяет время кода и может скрыть проблему.
Вместо этого попробуйте следующее ...
Оригинальный код:
object obj = new object();
lock(obj)
{
// Do stuff
}
Модифицированный код для отладки:
object _obj = new object();
object obj
{
get
{
System.Diagnostics.StackFrame frame = new System.Diagnostics.StackFrame(1);
System.Diagnostics.Trace.WriteLine(String.Format("Lock acquired by: {0} on thread {1}", frame.GetMethod().Name, System.Threading.Thread.CurrentThread.ManagedThreadId));
return _obj;
}
}
// Note that the code within lock(obj) and the lock itself remain unchanged.
lock(obj)
{
// Do stuff
}
Выставив obj
как свойство, хотя бы временно, с очень минимальными изменениями кода, вы можете определить, какая функция получила блокировку последней и в каком потоке - просто посмотрите на вывод Trace для последнего запись. Конечно, вы можете выводить любую другую информацию, которая может оказаться полезной и в геттере.
Нет, это не позволит вам определить, когда была снята блокировка, но если был выпущен своевременно, то у вас фактически не было проблемы конфликта блокировок.