Lock funktioniert nicht



  • // WTF: Zwischen diesen beiden Zeilen wird der komplette Code aus dem zweiten Teil ausgeführt...

    Wie jetzt? Steht das zweite Lock im Ersten?



  • Du hast nicht zufällig mehr als ein Tcp-Objekt?



  • @MFK
    Nein habe ich nicht und ich habe auch die Instanz des internen lockobjects im Debugger mit MakeObjectID überprüft. Es ist dasselbe Objekt 🙄

    @Jockelx
    Der zweite Block ist ein Teil der Methode HandleClient, welche als Delegate an BeginConnect des ersten blockes übergeben wird.

    Das hier habe ich aus der offiziellen Doku entnommen:

    When your application calls BeginConnect, the system will use a separate thread to execute the specified callback method, and will block on EndConnect until the Socket connects successfully or throws an exception.



  • using System;
    using System.Net;
    using System.Net.Sockets;
    
    namespace Fuck{
    class Program{
      private object obLoc;
      private bool   bErr;
    
      static void Main(string[] args){
       new Program();
       Console.In.Read();
      }
    
      public Program(){
       this.obLoc = new object();
    
       lock(this.obLoc) {
        Socket s = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
        s.Bind(new IPEndPoint(new IPAddress(new byte[] { 192,168,2,6 }),0));
        s.Ttl = 10;
        s.BeginConnect(new IPAddress(new byte[] { 192,168,2,8 }),80,this.HandleClient,null);
        if(this.bErr) Console.WriteLine("Schaaaaade, Windooooooof... Schaaaaade.....");
       }
      }
    
      private void HandleClient(IAsyncResult Result){
       lock(this.obLoc) {this.bErr = true;}
      }
    }
    }
    

    Dieser Code erzeugt denselben Fehler, allerdings tritt der Fehler nur im LAN mit einem sehr schnellen Netzwerk auf.



  • Oh Mann, nix verstehen aber immer gleich rummaulen. Schaaaaaaade Ishildur 🙄

    1. lock() lockt "rekursiv", d.h. du kannst im selben Thread das selbe Objekt mehrfach locken

    2. die BeginXxx Funktionen dürfen den CompletionHandler auch "direkt" aufrufen, also synchron, nämlich dann, wenn der IO sofort abgeschlossen wurde

    Was folgt daraus? Man muss beim Verwenden der BeginXxx Funktionen einfach aufpassen, dass es dem Programm nix ausmacht, wenn eben das passiert.

    Grmpf!



  • @hustbear
    Windoooof war eigentlich mehr im Scherz gedacht (nicht immer alles so ernst nehmen) :p
    Aber dass ich noch nicht viel davon verstehe, stimmt! Ich kenne mich zwar relativ gut mit Multithreading aus, allerdings nicht auf der .NET Plattform. 😉



  • Ich kenne mich zwar relativ gut mit Multithreading aus, allerdings nicht auf der .NET Plattform.

    Spielt denn die Plattform wirklich eine soooo grosse Rolle?
    Simon



  • @theta: naja mann muss schon die Spielregeln der Libraries kennen die man verwendet. Andere Libraries garantieren z.B. dass der Completion-Handler immer asynchron ausgeführt wird, auch wenn die Operation synchron abgeschlossen werden konnte. Das .NET Framework macht es aber anders. Wenn man das nicht weiss, bzw. nicht damit rechnet, fliegt man auf die Schnauze.



  • @hustbaer
    Genau das ist mir passiert 😃 Ich bin davon ausgegangen, dass der Code des delegates niemals ausgeführt werden kann, solange die Initialisierung der Client-/ und Serversockets nicht komplett abgeschlossen ist. Doch genau das passierte eben, wenn die Operation synchron ausgeführt wurde, weil dadurch das lock ausgehebelt wurde 😉

    Ich bedanke mich vielmals für die nützlichen Hinweise



  • "immer asynchron" ist IMO auch der bessere Weg, weil einfacher und daher weniger Fehleranfällig. IMO eine Fehlentscheidung, aber das .NET Framework ist ja geradezu voll davon.


Anmelden zum Antworten