Jeśli przekażesz typ wartości, zostanie on zablokowany, a następnym razem, gdy kod się tu uruchomi, zostanie ponownie zablokowany i nie będzie to ten sam obiekt dwa razy, więc nie da się go zablokować
lock(x)
{ ...
}
Blokada faktycznie odbywa się przez obiekt Monitor:
Powyższe jest równoważne z:
System.Object obj = (System.Object)x; System.Threading.Monitor.Enter(obj); spróbuj
{ ...
} w końcu
{ System.Threading.Monitor.Exit(obj);
}
A następnie, cytując oryginalne słowa MSDN: Użyj Monitora do blokowania obiektów (czyli typów odniesień), a nie typów wartości. Gdy przekazujesz zmienną typu avalue do Enter, jest ona oznaczana jako obiekt. Jeśli ponownie przekażesz tę samą zmienną do Enter, jest ona oznaczona jako osobny obiekt i wątek się nie blokuje. W tym przypadku kod, który Monitor rzekomo chroni, nie jest chroniony. Co więcej, gdy przekazujesz zmienną do Exit, powstaje jeszcze jeden osobny obiekt. Ponieważ obiekt przekazany do Exit różni się od obiektu przekazanego do Enter, Monitor rzuca SynchronizationLockException. Więcej informacji można znaleźć w temacie koncepcyjnym Monitorzy. |