2016-09-21 2 views
0

Ein Nachfolger zu this post. Mein Ziel ist es nur eine Calculate zu einer Zeit zu haben, so habe ich eine SyncLock hinzugefügt:Ist es sicher, SyncLock und MemoryBarrier aufzurufen, auch wenn Sie nicht in einem separaten Thread sind?

Public Sub Calculate(Optional inBack As Boolean = True) 
    If Not inBack Then 
     InternalCalculate(-1, False) 
    Else 
     If CalcThread IsNot Nothing Then 
      CalcThread.Abort() ' yes, I will replace this 
      CalcThread = Nothing ' XXX 
     End If 
     If CalcThread Is Nothing Then 
      CalcThread = New Threading.Thread(AddressOf InternalCalculate) 
      CalcThread.IsBackground = True 
     End If 
     CalcThread.Start() 
    End If 
End Sub 

Private Sub InternalCalculate(Optional Line As Integer = -1, Optional isBack As Boolean = True) 
    Dim Lock As New Object 
    SyncLock Lock 
     Threading.Thread.MemoryBarrier() ' do this BEFORE a write, right? 
     isRunning = true 
     'do the expensive stuff 
    End SyncLock 
End Sub 

Notiere die isBack. Wenn dies falsch ist, sollte der Code nur in main ausgeführt werden. Dies wird häufig verwendet, wenn ein einzelner Line neu berechnet wird. Also meine Frage ist über die Sicherheit dieser beiden Linien:

SyncLock Lock 
Threading.Thread.MemoryBarrier() 

Es ist mir nicht klar, in the documentation, was passiert, wenn ich diese in Code ausgeführt wird in Haupt nennen. Ich habe den Code hinzugefügt, und es scheint zu laufen, OK, aber ich möchte sicherstellen, dass ich mich nicht zu einem anderen Gotcha öffne, wie Abort. Sind diese OK für beide Anwendungen mit und ohne Gewinde?

+0

Der Begriff 'thread' ist die Abkürzung für' thread of execution' und kurz gesagt, alles ist ein Thread, daher der Begriff 'single threaded "für ein Programm, das keine Threads verwendet. 'main' selbst läuft in einem Thread, es kann einfach der * einzige * Thread sein und hat keine besondere Arbeit. Jeder Prozess hat einen Standard-Thread. – kfsone

+0

Sicher, aber ein * Sync * Lock ist zum * Synchronisieren * Threads. Wenn es nur einen Thread gibt, gibt es nichts zu synchronisieren *. Also meine Frage. –

Antwort

1

Ja, es ist sicher, sie in Single-Thread-Code zu verwenden.

Es gibt jedoch Probleme mit Ihrer InternalCalculate, die es ermöglicht, Code gleichzeitig auszuführen. Bei jedem Aufruf von InternalCalculate wird ein neues Objekt Lock erstellt. Synclock blockiert nur Threads, wenn diese das gleiche Objekt verwenden, also Lock eine Readonly-Membervariable machen.

Wenn Sie dann mehrere Threads ausführen, wird der zweite, dritte, vierte usw. warten, bis der erste, der die Sperre erhält, den Sync Lock Block verlässt. Dann werden die anderen gehen. Also, wenn dies Code ist, der nur einmal ausgeführt werden sollte, sollten Sie das Double Check Lock Pattern überprüfen.

Anstatt MemoryBarriers für das Lesen/Schreiben von flüchtigen Daten hinzuzufügen, würde ich vorschlagen, dass Sie System.Threading.Thread.VolatileRead und System.Threading.Thread.VolatileWrite verwenden. Dann müssen Sie sich nicht merken, in welcher Reihenfolge Sie Ihre Lese-/Schreibvorgänge ausführen.

+0

Vielen Dank @ FloatingKiwi! Ich werde die Änderung zu Lock ASAP machen - dieser Code kommt direkt von einem MS-Beispiel und ich war selbst neugierig auf dieses Thema. Reicht es aus, die Deklaration einfach außerhalb des Subs und in das umschließende Objekt zu verschieben? Brauche ich wirklich eine Immobilie? –

+0

Ein Follow-up: Da die Verbraucher der isCalculating bool verteilt sind, bedeutet das, dass sie alle VolatileRead verwenden müssen? Oder ist ein VolitileWrite innerhalb des Threads genug, um sicherzustellen, dass die Verbraucher in Main OK sind? –

+0

Mein Vorschlag war ein Readonly-Feld, keine Readonly-Eigenschaft. Dadurch wird deutlich, dass Sie ein Sperrobjekt pro Instanz Ihrer Klasse erstellen. In Bezug auf den volatilen Code würde ich den Code so umstrukturieren, dass er überhaupt nicht benötigt wird. Zum Beispiel ändern Sie berechnen zu einer Funktion, die Ihr Ergebnis zurückgibt. Ohne zu sehen, was Sie berechnen/wie Sie mit Ihren Objekten interagieren, ist es schwer zu sagen. – FloatingKiwi

Verwandte Themen