2013-01-17 5 views
7

Ich habe die folgende Situation: Ich möchte den Zugriff auf ein Objekt gleichzeitig ausschließen.Können Schloss und Monitor auf demselben Objekt sicher verwendet werden?

Bisher normaly würde ich ein Sperrobjekt

object lockObject = new object(); 
... 

method1: lock(lockObject) { CODE1 } 

Jetzt benutze ich habe auch ein Verfahren, das von einem anderen Thread aufgerufen werden kann. Es sollte nicht für eine unbekannte Zeit blockiert werden, stattdessen sollte es eine Antwort in einer definierten Zeit geben.

In diesem Fall ich einen Monitor verwenden würde, wie

method2: 
try{ 
    Monitor.TryEnter(lockObject , 20000, ref lockTaken); 
    if (lockTaken) {CODE2} 
} 
catch(...){...} 
finally 
{ 
    if (lockTaken) Monitor.Exit(timerLock); 
} 

Nun meine Frage: sperren und Monitor so gemischt werden, wenn die LockObject gleich ist und sich gegenseitig ausschließen, oder würde Es wird benötigt, um jede Sperre auf einen Monitor zu ändern.

Also beide Male das gleiche Token "gesperrt" sein, oder würde der Monitor ein anderes Token für das Objekt dann die Sperre erstellen?

Auf einen Blick kann ich nicht sehen, dass die Anwendung im Code von beiden zur gleichen Zeit läuft. Aber ich weiß nicht, ob Timing-Probleme existieren können, wo CODE1 und CODE2 parallel ausgeführt werden.

+1

Ich fühle deinen Schmerz; Ich wünschte oft, dass das 'lock'-Schlüsselwort irgendwie eine Zeitüberschreitung hat –

Antwort

6
lock (sync) 
{ 
    return World(); 
} 

Würde in der Intermediate Language in die Zeilen schauen.

L_0007: call void [mscorlib]System.Threading.Monitor::Enter(object) 
L_000c: call int32 Hello::World() 
L_0011: stloc.0 
L_0012: leave.s L_001b 
L_0014: ldloc.1 
L_0015: call void [mscorlib]System.Threading.Monitor::Exit(object) 

Also sollte es in Ordnung sein. Sie sind technisch gleichwertig.

+0

Beachten Sie, dass neuere Versionen von csc, wenn Sie auf .NET 4 oder höher abzielen, unterschiedliche ILs haben. –

+0

Danke, stimmt. Habe es einfach zur groben Illustration gemacht. –

5

kann sperren und überwachen so gemischt werden, wenn die LockObject die gleiche ist und schließen sich gegenseitig

Ja, das absolut sicher ist und es wird funktionieren. Die lock { }-Anweisung wird in Aufrufe von Monitor.Enter() und Monitor.Exit() umgeschrieben. Es ist nur kurz, sehr ähnlich der using() {} Aussage.

Von MSDN:

lock (x) ... 

wird

System.Threading.Monitor.Enter(x); 
try { 
    ... 
} 
finally { 
    System.Threading.Monitor.Exit(x); 
} 

Und nach dem Kommentar, in Fx4 und später kann es Monitor.TryEnter() verwenden. Aber die einfache Version oben beantwortet Ihre Frage.

+2

Oder Monitor.TryEnter, wenn es auf .NET 4+ abzielt. –

Verwandte Themen