Czy jest potrzeba używania lock w get, jeśli w set jest?

0

Czy jest potrzeba używania lock w get, jeśli w set jest? Tak na logikę, to jeśli na set jest lock, to pobierając wartość chyba nie powinno być problemów, bo gdyby równolegle chciało się ją ustawic, to wtedy pobieranie powinno się zatrzymać lub wykonać się pierwsze? xD
Mówię o czystych właściwościach, po prostu ustawienie i zwracanie wartości, bez jakiejś specjalnej logiki.

1

ogolnie to kazdy dostep do mutowalnej zmiennej powinien byc synchronizowany. jest od tego pare wyjatkow zaleznych od typu danych czy dokonywanych operacji, przy czym zamiast myslec gdzie by tu opuscic locka po prostu staraj sie robic niemutowalne klasy.

0
  1. lock w set w żaden sposób nie blokuje get tak jak to napisałeś
  2. lock w set jest po to aby cały set był operacją atomową (jeśli masz w set logikę bo jeśli jest to proste przypisanie to lock w 99% przypadków jest zbędny)
  3. w get rzadko kiedy jest jakaś logika. Szczególnym przypadkiem może być tutaj np. singleton thread-safe gdzie lock jest jak najbardziej pożądany http://csharpindepth.com/Articles/General/Singleton.aspx
0

A w ten sposób?

public class CLass
    {
        public void SetString(string Value)
        {
            lock (locker)
            {
                String = Value;
                // jakaś logika, inicjalizowanie zmian w serwisie
            }
        }

        public string String { get; private set; }

        private readonly object locker;
    }

Czy teraz pobieranie wartości String jest bezpieczne?

0
Biały Pomidor napisał(a):

A w ten sposób?

public class CLass
    {
        public void SetString(string Value)
        {
            lock (locker)
            {
                String = Value;
                // jakaś logika, inicjalizowanie zmian w serwisie
            }
        }

        public string String { get; private set; }

        private readonly object locker;
    }

Czy teraz pobieranie wartości String jest bezpieczne?

Nie wiem, ale to nie jest czytelny zapis. Używasz domyślnych akcesorów w sytuacji kiedy właśnie o nie ci nie chodzi (a przynajmniej w przypadku set).

public class CLass
{
    public string String
    {
        get
        {
            return _string;
        }
        set
        {
            lock (locker)
            {
                _string = value;
                // jakaś logika, inicjalizowanie zmian w serwisie
            }
        }
    }
    private string _string;
    private readonly object locker;
}
0

I jeżeli polę String będzie modyfikowane tylko w tym miejscu poprzez set (żaden asynchroniczny kod nie modyfikuje tego pola) to będzie wszystko dobrze?

0

tak

0

Czy jest potrzeba używania lock w get, jeśli w set jest? Tak na logikę, to jeśli na set jest lock, to pobierając wartość chyba nie powinno być problemów, bo gdyby równolegle chciało się ją ustawic, to wtedy pobieranie powinno się zatrzymać lub wykonać się pierwsze? xD

Jeśli lock jest tylko w set, to get nie będzie na nic czekać, ani nie będzie zatrzymywać seta. Konstrukcja lock jest właśnie od czekania, więc tam gdzie nie ma locka tam nie ma czekania. Zatrzymywanie jest podczas wejścia do sekcji lock oraz przy wykonywaniu instrukcji Monitor.Wait.

0

jeżeli nie masz żadnej logiki która powinno się odpalić tylko jednorazowo jednocześnie to lock nie jest Ci potrzebny, tylko spowolni kod
string jest typem niemutowalnym (niemodyfikowalnym), przypisanie i odczyt referencji do stringa (jak i jakiejkolwiek innej referencji) jest operacją atomową a string w konkretnym miejscu pamięci nie może się zmienić

taka klasa będzie w 100% thread-safe:

public class Class
{
  public string String { get; set; }
}
2

Błękitny Kot:
Być może będzie thread-safe, ale niekoniecznie będzie działać poprawnie. Żeby odczyt i zapis z wielu wątków działał w miarę przewidywalnie trzeba dodać modyfikator volatile: https://docs.microsoft.com/pl-pl/dotnet/csharp/language-reference/keywords/volatile Inaczej wartość referencji w jednym wątku może być siedzieć sobie w rejestrze procesora (bo kompilator sobie optymalizuje), a więc ten wątek nie będzie widział zmian z drugiego wątku dopóki zawartość rejestru nie będzie odświeżona. volatile zapobiega cacheowaniu wartości zmiennych w rejestrach.

1 użytkowników online, w tym zalogowanych: 0, gości: 1