2009-01-07 13 views
13

Czytałem o wątkach i blokowaniu. Powszechną praktyką jest, że nie można (nie powinno się) blokować typu wartości.Jak prawidłowo zablokować typ wartości?

Pytanie brzmi, jaki jest zalecany sposób blokowania typu wartości? Wiem, że jest kilka sposobów na zrobienie jednej rzeczy, ale nie widziałem żadnego przykładu. Chociaż na forum MSDN był dobry wątek, ale nie mogę tego teraz znaleźć.

Dzięki

+2

Czy jesteś w 100% pewien, że trzeba zablokować podczas modyfikowania obiektu typu wartość? Kiedy taki nagi przedmiot jest przekazywany z jednego wątku na drugi, tworzona jest kopia, więc wątki kończą się na 2 różnych obiektach, co jest bezpieczne. –

Odpowiedz

16

Użyj innego obiektu do blokady.

int valueType; 
object valueTypeLock = new object(); 

void Foo() 
{ 
    lock (valueTypeLock) 
    { 
     valueType = 0; 
    } 
} 
+5

Pamiętaj, aby obiekt blokady był tylko do odczytu lub można go zmienić na inny obiekt. Założona blokada może w tym przypadku wyjść poza okno. –

+1

Należy również zauważyć, że ten konkretny przykład jest ściśle akademicki. Żadna rozsądna osoba nigdy nie umieściłaby 'blokady' wokół prostego przypisania zmiennej' int'; Przypisanie ma charakter atomowy, a zapewnienie aktualnej widoczności zapisu można osiągnąć skuteczniej i łatwiej, używając słowa kluczowego 'volatile' w deklaracji pola. –

1

zależy od sytuacji, może być w stanie uniknąć używania blokad wykorzystując System.Threading.Interlocked ten sam kod w przykładzie Jona staje:

System.Threading.Interlocked.Exchange(valueType,0) 
14

Twoje pytanie jest sformułowane w taki sposób, że sugeruje mi, że nie do końca rozumiesz blokowanie. Nie blokujesz danych, blokujesz, aby chronić integralność danych. Obiekt, który blokujesz, jest nieistotny. Liczy się to, że blokujesz ten sam obiekt w innych obszarach kodu, które zmieniają chronione dane.

+0

Dobre wyróżnienie – JoshBerke

+0

Dobrze wyjaśnione. –

0

mam zawsze przy użyciu oddzielnej zmiennej blokady:

object syncObj = new object(); 

void Foo() 
{ 
    lock(syncObj) 
    { 
    // do some stuff 
    } 
} 

Blokowanie na wartości typów nie ma sensu, bo i tak wartość typy są niezmienne i nie mogą być modyfikowane. Blokowanie "tego" jest również problematyczne, ponieważ "to" jest widoczne dla zewnętrznego świata.

Dla niektórych informacji o tym, jak monitor był pierwotnie przeznaczony do stosowania zobaczyć Monitor (synchronization)

+0

Err, obiekty typu wartości nie są naprawdę niezmienne. Kiedy mówię int i = 0; ++ i; Właśnie zmodyfikowałem obiekt typu wartości. –

+2

Nie, przypisałeś nową wartość do zmiennej, ale nie zmutowałeś typu wartości. typy-wartości to "wartości". 1 to zawsze 1. 1 + 1 to wartość 2, ale nie zmienia się wartości 1 do 2. można modyfikować złożone typy wartości (aka structs), chociaż jest to również uważane za (bardzo) złe praktyki. –

+0

_ "typy-wartości są niezmienne i nie można ich zmodyfikować" _ - dotyczy to pierwotnych typów wartości, ale nie ogólnie typów wartości. Typy wartości _should_ powinny być implementowane jako niezmienne, ale wiele z nich nie jest (np. [Rectangle] (https://msdn.microsoft.com/en-us/library/system.drawing.rectangle (v = vs.110) .aspx)) . W każdym razie nie jest to niezmienność (lub nie) typu wartości, dlatego blokowanie tego typu nie ma sensu. Chodzi o to, że nie można zablokować typu wartości, ponieważ nie ma on monitora. Uważam, że ta odpowiedź jest bardzo niedokładna i myląca. –