2016-07-04 13 views
-3

Ich habe das folgende Sperrungsszenario, das hin und wieder eine Sperre zu verpassen scheint und 2 Code-Instanzen parallel laufen lässt. Ich würde mich über Ihre Hilfe bei der Analyse/Korrektur des Codes freuen.C# Sperre funktioniert nicht (?)

public delegate void _D(A a);  

namespace ExternalDll { 
    public event _D D; 
} 

namespace MainSpace { 
    ExternalDll _externalDll; 
    public static object lockObj = new object(); 
    public static int counter = 0; 
    . 
    . 
    _externalDll.D += new _D(myEventHandler); 
    . 
    . 
    void myEventHandler(A a) { 
     lock (lockObj) { 
      counter++; 
      // do staff, printouts, etc. 
      Console.WriteLine("First={0}\n", counter); 
      // do other staff 
      Console.WriteLine("Second={0}\n", counter); 
     } 
    } 
} 

ExternalDll ist eine DLL-Datei, die ein (von Typ A) mit Informationsnetzwerkkommunikation empfängt. Es ruft das Ereignis D mit a als Eingabe auf.

Der Hauptnamespace registriert myEventHandler für das Ereignis D, das von ExternalDll ausgelöst wird. In myEventHanlder gibt es eine Sperre. Das erwartete Verhalten besteht darin, dass der Code innerhalb des Sperrabschnitts nicht mehr als einmal ausgeführt wird.

Wenn jedoch die Anwendung ausgeführt wird, kommt es manchmal zu einer Situation, in der der gesperrte Code zweimal "parallel" ausgeführt wird. Zum Beispiel könnte ich sehe Ausdrucke wie:

First=0 
First=1 
Second=0 
Second=1 

Dies geschieht vor allem in Fällen von stoßweise Netzwerk-Ereignissen, die innerhalb kürzester Zeitdauer (< 1us) an die externalDll ankommen.

Meine Fragen/Anfragen sind:

  • Was die lock-Anweisung dieses fehlerhafte Verhalten machen könnte. 2 Instanzen des gesperrten Codes zulassen?

  • wie der Code verbessert wird, damit es das gewünschte Verriegelungsverhalten gibt.

Danke,

-Moshe.

+3

Es sperrt die Variable 'theLock' aber ich sehe keinen Wert zugewiesen, wollte es nicht' lockObj' sperren? – prospector

+0

Gibt es anderes Code schreiben, um zu widersprechen? – usr

+0

Wie oben erwähnt, verwendet der Beispielcode "theLock", impliziert jedoch, dass "lockObj" verwendet werden sollte. Vielleicht dein Beispiel ein wenig aufräumen? Abgesehen davon ruft "// andere Mitarbeiter" alles auf, was zu einem weiteren Rückruf führen würde, bevor der Event-Handler beendet wird? –

Antwort

0

Ich weiß nicht genug zu sagen. Eine Vermutung wäre, dass zwei App-Domains erstellt werden, weil Sie etwas verwenden, das mehrere App-Domains erzeugt, z. Asp.net tut dies manchmal für HTTP-Module.

+0

Ja, sehr wahrscheinlich, dass die OP seine Anwendung zahlreiche beginnt mal. – VMAtm

+0

Meine Anwendung ist einfach zu berechnen, kein Webserver oder etwas ähnliches. Ich sehe nur ein einziges Konsolenfenster, während es läuft. – Moshe

+0

Vielleicht drucken Sie auch die Adresse von lockObj, um zu sehen - könnte der Marshaller etwas komisches tun. – keith