2011-01-12 7 views
0

VB.NET, .NET 4VB.NET Synchronisation Verwirrung

Hallo an alle,

Ich habe eine Anwendung, die ein industrielles System steuert. Es hat eine GUI, die nach dem Start eines Prozesses prinzipiell die Zustände verschiedener angeschlossener Geräte anzeigt. Es funktioniert grundsätzlich wie folgt:

  • Ein System.Timers.Timer-Objekt wird immer ausgeführt. Bei jedem Elapsed-Ereignis fragt es die Geräte nach ihren aktuellen Werten ab und ruft Steuerelemente auf der GUI auf, die mit den neuen Werten aktualisiert werden.
  • Eine Starttaste angeklickt wird, wird ein Prozess Zeit Stoppuhr-Objekt erstellt und (Labels auf der GUI werden nun aufgerufen und aktualisieren auf den System.Timers.Timer des Abgelaufene Ereignis, zusätzlich zu den anderen Arbeiten begonnen, die Pflege auf genommen wird Dieses Ereignis)
  • ein neuer Thread erzeugt wird, die einen Prozess läuft Methode() Subroutine
  • Einige Stoppuhr Objekte erstellt werden und gestartet (diese Stoppuhr werden periodisch während des Prozesses über ihren Neustart (eingestellt).
  • einig Logik ist ausgeführt auf die ElapsedMilliseconds Eigenschaften neuen Stopwatchs, um zu bestimmen, wenn die Dinge zu tun, wie schreiben neue Sollwerte an die Geräte, das Datenprotokoll aktualisieren, etc ...

Hier ist mein Problem: Das Programm gelegentlich friert. Meine unwissenden Bemühungen, das Problem aufzuspüren, haben mich zu der Vermutung gebracht, dass das Lesen/Schreiben in die Untergruppe von Geräten, die RS-232-gesteuert sind, meistens die Schuldigen sind. Allerdings sehe ich gelegentlich andere seltsame Dinge auf Programm einfrieren, beispielsweise eines der Zeit Labels, deren Eigenschaft Text durch ein manchmal ElapsedMilliseconds Unterkunft Stoppuhr bestimmt wird, ein unmögliches Wert (beispielsweise -50 Stunden oder so) zeigen.

Für die RS-232 Probleme, vermute ich, so etwas wie ein Leseereignis wird als ein Schreibereignis und dies führt zu einem Einfrieren (?) Zur gleichen Zeit ausgeführt werden. Ich habe versucht, dies zu verhindern, indem sichergestellt wird, dass die gesamte Kommunikation mit einer RS-232-Gerät über einen Transmit() Unterprogramm geschleust wird, die das folgende Attribut hat:

Which, so weit meine Unwissenheit mir erlaubt, zu verstehen, , sollte erzwungen werden, dass eine Transmit() - Ausführung vollständig beendet wird, bevor eine andere starten kann. Ein weiteres Risiko besteht darin, dass der Code hier blockiert wird, wenn ein Transmit() niemals beendet wird?

In Bezug auf die Stoppuhr Problem, ich spekuliere, dass das Problem ist, dass der Timer versucht, eine GUI-Label zur gleichen Zeit, die Stoppuhr die Restart() -Methode ausgeführt wird, zu aktualisieren. Ich bin mir nicht sicher, ob dies ein Problem verursachen könnte. Alles, was ich weiß, ist, dass dieses Problem nur zu einem Zeitpunkt im Prozess auftrat, als ein Restart() -Aufruf gemacht wurde.

Ich frage mich, ob ich einen SyncLock oder etwas sperren Sie eine Stoppuhr, während das Etikett (oder umgekehrt, während sein Sein neu gestartet) wird aktualisiert verwenden könnte? Oder vielleicht soll ich den Timer stoppen, starten Sie die Stoppuhr, und dann den Timer starten wieder, wie so ?:

Timer.Stop 
Stopwatch.Restart 
Timer.Start 

Meine Beklommenheit darüber, wie zu meinem völligen Mangel an Verständnis dafür, wie die .NET-Synchronisations aufgrund gehen Objekte funktionieren tatsächlich. Ich habe versucht, ein paar SyncLocks an verschiedenen Stellen zu schlagen, aber ich habe wirklich keine Ahnung, ob sie korrekt implementiert sind oder nicht. Ich frage mich, ob, nachdem ich all diesen Kontext bereitgestellt habe, jemand, der wirklich schlau ist, mir sagen könnte, wie dumm ich bin und wie ich das richtig machen kann. Ich würde jeden Input sehr schätzen.Wenn es nützlich wäre, ein paar Code-Snippets zur Verfügung zu stellen, würde ich mich darüber freuen. Ich mache mir nur Sorgen, dass alles so verworren ist, dass es nur von der erhofften konzeptionellen Frage ablenken würde.

Vielen Dank im Voraus! Brian

+1

Ugh, ich hasse Fragen wie diese, nur ein Kommentar, weil eine Antwort nie geschätzt wird. Du hast ein sehr ernstes Problem, wahrscheinlich schlimmer als du denkst. Sie haben Threads, die ohne Synchronisation laufen. Sie verwenden den absolut schlechtesten Weg, um sie zum Laufen zu bringen, System.Timers.Timer saugt, weil es nur einen anderen Thread startet, auch wenn das letzte Elapsed-Ereignis noch nicht abgeschlossen war. Dies ist eine der harten Lektionen des Threading, beginnen Sie über Version 2.0 nachzudenken –

+0

Nur eine Anmerkung über RS232 ... Sie können gleichzeitig senden und empfangen. Auch ja, einige RS232-zu-USB-Hardware ist ziemlich flockig und kann allerlei Ärger verursachen. Sie sollten jedoch den Ratschlag von Hans befolgen, da Threading hier das Hauptproblem darstellt. – Brad

+0

Entschuldigung Hans. Mir ist klar, dass meine Frage vage ist. Ich bin sehr amateurhaft im Programmieren, versuche nur meinen Weg zu finden. Ich denke, ich werde anfangen, an einer Version 2 zu arbeiten, die den Vorschlag von Greg implementiert, sich auf einen Scheduler zu verlassen. Das hat den zusätzlichen Vorteil, dass man sich mehr auf den Code von kompetenten Programmierern und weniger auf meinen eigenen Müll verlässt. Ich frage mich allerdings, was genau man vermuten würde, würde zu einer Aussage wie "Threading ist wahrscheinlich das Hauptproblem hier" führen? Ich verstehe nicht genug, um herauszufinden, welche Risiken beim Threading bestehen. –

Antwort

1

Ich würde eine Verschiebung zu einem Task-Scheduling-Framework betrachten, anstatt sich auf manuelle Manipulation von Timern zu verlassen, wenn Sie an irgendwas SCADA arbeiten. Ein einfacher Startpunkt wäre etwas, das den Klassen hardcodet.Scheduling ähnlich ist, und Sie können zu etwas wie dem Biest wechseln, das Quartz ist. Die meisten dieser Frameworks bieten Ihnen die Möglichkeit, geplante Aktionen anzuhalten und fortzusetzen.

Wenn ich mit Modbus arbeite, behalte ich normalerweise einen lokalen Cache der Registerwerte und führe Änderungen an einem beliebigen Wert durch, um ein Änderungsereignis auszulösen. Dies hat den Vorteil, dass Sie Dinge wie das Aktualisieren von Werten manuell implementieren können, ohne Ihre Prozessplanung zu beeinträchtigen und bei der Auswertung der abgefragten Antwort auf Totzone zu prüfen. Dies war der Nebeneffekt der Implementierung eines abgefragten Protokolls in eine Teilmenge der OPC-DA-Schnittstelle.

+0

Obwohl ich nicht gerade eine Antwort auf meine nebulösen Fragen bin, habe ich über Quarz gelesen und getestet. Ich wünschte wirklich, ich hätte das vor Monaten gewusst! Danke, dass du es aufgezeigt hast. –