Verstehe folgende "Interlocked.Exchange" code nich:(



  • Hallo Leute,

    ich kannte bis her Interlocked.Exchange nicht, und habe
    gelesen, code quasi atomar ausgeführt wird... hmmm..

    und bin dan auf diesen Code gestoßen (mit using block)?

    using (var locaClient = Interlocked.Exchange(ref _client, null))
               {
                   if (localClient == null)
                       return;
    
                   await localClient.DisconnectAsync().ConfigureAwait(false);
               }
    

    was passiert hier... wäre das das gleich mit "lock(_client){...}



  • Wenn du eine Analogie mit lock möchtest, dann wäre

    localClient = Interlocked.Exchange(ref _client, null)
    

    mit sowas vergleichbar:

    lock (mutexVariableFor_client) {
        localClient = _client;
        _client = null;
    }
    

    Üblicher wäre es aber zu sagen dass object Exchange (ref object location1, object value) sinngemäss das macht:

        public static object Exchange (ref object location1, object value) {
            // with one atomic access to `location1`:
            object ret = location1;
            location1 = value;
    
            return ret;
        }
    

    D.h. wenn mehrere Threads gleichzeitig versuchen sich mit Interlocked.Exchange(ref _client, null) die Referenz aus _client "rauszunehmen", dann bekommt genau einer eine non-null Referenz und alle anderen bekommen null. (Natürlich vorausgesetzt die Referenz war davor überhaupt non-null.)

    Du kannst Interlocked.Exchange auch mit anderen Interlocked Funktionen kombinieren. Die Zugriffe auf location1 sind dabei immer atomar und können dabei von anderen Zugriffen über Interlocked Funktionen nicht unterbrochen werden.



  • Achso, d.h. in dem Beispiel sind für alles andere Aufrufen von _client ==null, während der code

       ```csharp
    

    {
    if (localClient == null)
    return;

               await localClient.DisconnectAsync().ConfigureAwait(false);
           }
    
    
    ausfeührt wird, sp dass sicher gestellt ist, das beim freigeben des clients , alle andee nich mehr zugriefen!?
    
    sprich der code 
    
    ```csharp
    object ret = location1;
            location1 = value;
    
    ist in dem sinn eine atomare operation!?
    


  • @SoIntMan
    Den ersten Teil deines Beitrages verstehe ich nicht. Ist zu wirr. Sorry.

    sprich der code

    object ret = location1;
            location1 = value;
    
    ist in dem sinn eine atomare operation!?
    

    Ja, genau.
    "interlocked exchange" oder "atomic exchange" heisst dass du damit eine Variable überschreiben kannst, dabei aber ihren alten Wert zurückbekommst, und zwar so dass dieses "erst lesen und dann überschreiben" eben atomar ist.

    Ohne diese Atomizität könnte es nämlich passieren dass zwei Threads gleichzeitig erstmal den selben alten Wert lesen, und dann erst beide einen neuen drüberschreiben. Mit Atomizität kann nur ein Thread den alten Wert bekommen, der zweite muss den neuen Wert bekommen den der erste Thread drübergeschrieben hat.

    Wenn du jetzt z.B. ein Objekt "konsumieren" möchtest*, und es sein kann dass mehrere Threads gleichzeitig diesen Code ausführen, dann ist das natürlich doof. Weil es ja nur einer konsumieren kann/darf. Daher darf es auch nur einer (der erste) bekommen. Und der zweite muss das bekommen was der erste als Ersatz angegeben hat. Also in diesem Beispiel null, also nix.

    *: In deinem Beispiel wird der Client ja erstmal disconnected und dann durch den using Block disposed. D.h. er kann danach nicht mehr verwendet werden, wurde also quasi "verbraucht". Das meine ich hier mit "konsumieren".



  • Hallo Husbaer,

    danke für die Erklärung, habe es soweit verstanden. Die Interlockt.Exchange mach somit deise beiden Zeilen code:

    object ret = location1;
    location1 = value;
    

    atomar.
    So wird in meinem Beispiel (Was in dem gesamten Code nicht ersichtlich ist) , dafür gesorgt, dass wenn ich "DisconnectAsync" ausführe, er nicht gleichzeig ein read/write oder sogar ein reconnect auf die selbe instance macht, sonder das disconnect mit der "überbrügung intanz vornimmt, und die alte schon null ist"

    Richtig?;)



  • @SoIntMan

    1. Wenn du was von mir wissen willst ist es schlau wenn du "@hustbaer" schreibst und nicht "Husbaer". Weil ich bei "@hustbaer" sehe dass mich jemand getaggt hat, bei "Husbaer" dagegen nicht. Also auch nicht wenn du es richtig geschrieben hättest statt das "t" wegzulassen.

    2. Woher soll ich wissen was der Code macht den du mir nicht zeigst?

    3. Was soll sonder das disconnect mit der "überbrügung intanz vornimmt, und die alte schon null ist" heissen? Erstmal is da wohl ein dass-das Fehler drin. Dann fehlt bei "sonder" wohl ein "n" am Schluss? Und dann ... "überbrügung"? Dafuw? Und selbst wenn ich annehme dass du "überprüfung" schreiben wolltest wird da immer noch kein für mich verständlicher Satz draus.


Log in to reply