Как уже говорили другие, lock
"эквивалентно"
Monitor.Enter(object);
try
{
// Your code here...
}
finally
{
Monitor.Exit(object);
}
Но просто из любопытства, lock
сохранит первую ссылку, которую вы передадите ей, и не сгенерирует, если вы изменитеЭто. Я знаю, что не рекомендуется менять заблокированный объект , и вы не хотите этого делать.
Но опять же, для науки, это прекрасно работает:
var lockObject = "";
var tasks = new List<Task>();
for (var i = 0; i < 10; i++)
tasks.Add(Task.Run(() =>
{
Thread.Sleep(250);
lock (lockObject)
{
lockObject += "x";
}
}));
Task.WaitAll(tasks.ToArray());
... И это не так:
var lockObject = "";
var tasks = new List<Task>();
for (var i = 0; i < 10; i++)
tasks.Add(Task.Run(() =>
{
Thread.Sleep(250);
Monitor.Enter(lockObject);
try
{
lockObject += "x";
}
finally
{
Monitor.Exit(lockObject);
}
}));
Task.WaitAll(tasks.ToArray());
Ошибка:
Исключение типа 'System.Threading.SynchronizationLockException' произошло в 70783sTUDIES.exe, но не было обработано в коде пользователя
Дополнительная информация: Метод синхронизации объектов был вызван из несинхронизированного блока кода.
Это потому, что Monitor.Exit(lockObject);
будет действовать на lockObject
, который изменился, потому что strings
неизменны, тогда вы вызываете его из несинхронизированного блока кода ... но в любом случае.Это просто забавный факт.