Fragensteller
Warteschlange für verschiedene Methoden erstellen

Allgemeine Diskussion
-
Guten Abend,
ich habe einen RS-232-Controller, der mittels Software zu Steuern ist. Ich habe eine Klasse erstellt, in der mehrere Methoden (z.B. lesen und schreiben von Werten) definiert sind.
Nun kann ich diesem Controller immer nur 21 ASCII Zeichen in einem Befehl senden, da manche befehle länger sind, muss ich das senden oder empfangen in mehreren Schritten mit Pausen dazwischen durchführen. Somit benötigt das senden und empfangen einige Zeit (sekunden).
Nun habe ich einen asynchronen Timer definiert, der einmal pro Sekunde Werte vom Controller abruft. Nebenbei müssen aber auch andere Befehle an den Controller gesendet werden.
Jetzt ist also das Problem, das sich manche befehle überschneiden, wenn ein Befehl gesendet wird, während das Programm zeitgleich den Timer durchläuft.
Hat jemand eine Idee, wie man das Problem lösen kann? Ich dachte da evtl. an eine Art Warteschleife, die zum Beispiel wartet bis der Timer durchgelaufen ist, erst dann einen anderen Befehl abarbeitet und dann wieder den Timer startet. Also so das sich die Befehle bei Senden und Empfangen nicht überscheiden.
Hier mal ein ausschnitt aus dem Programm:
////// MainWindow.cs ////////////// private async void Timer_Tick(object sender, EventArgs e) { await AsyncTimer(); } private async Task AsyncTimer() { Timer.Stop(); string[] temperatures = await controller.TempController_ReadTemperature(); Cell1_Temperature.Text = temperatures[0] + " °C"; Cell2_Temperature.Text = temperatures[1] + " °C"; Cell3_Temperature.Text = temperatures[2] + " °C"; Cell4_Temperature.Text = temperatures[3] + " °C"; Timer.Start(); return; } private void ApplyBtn_Click(object sender, RoutedEventArgs e) { int[] setpoints = new int[] { Cell1_SetPoint.Value.Value, Cell2_SetPoint.Value.Value, Cell3_SetPoint.Value.Value, Cell4_SetPoint.Value.Value }; controller.TempController_SendSetPoints(setpoints); bool[] Zones = new bool[4] { false, false, false, false }; if (Cell1_SetPoint.Value < 30) { Zones[0] = false; } else { Zones[0] = true; } if (Cell1_SetPoint.Value < 30) { Zones[1] = false; } else { Zones[1] = true; } Zones[2] = (Cell1_SetPoint.Value < 30) ? false : true; Zones[3] = (Cell1_SetPoint.Value < 30) ? false : true; controller.TempController_ZoneEnable(Zones); } ////// Controller.cs /////// Klasse public void TempController_ZoneEnable(bool[] zones) { StringBuilder Z1 = new StringBuilder(); byte zone4; if (zones[3]) { zone4 = 0x31; } else { zone4 = 0x30; } Z1.Append("00000"); for (int i = 2; i >= 0; i--) { if (zones[i]) { Z1.Append("1"); } else { Z1.Append("0"); } } byte zone1 = Convert.ToByte(Z1.ToString(), 2); byte[] convertedzones = ASCIIEncoding.ASCII.GetBytes(zone1.ToString()); Thread.Sleep(100); myController.MODULE_6_OUT.ByteArray[0] = 0x2B; myController.MODULE_6_OUT.ByteArray[1] = 0x4C; // Zeichen 1 myController.MODULE_6_OUT.ByteArray[2] = 0x30; myController.MODULE_6_OUT.ByteArray[3] = 0x6A; myController.MODULE_6_OUT.ByteArray[4] = zone4; // Zone enable 1 myController.MODULE_6_OUT.ByteArray[5] = convertedzones[0]; // Zone enable 2 myController.MODULE_6_OUT.ByteArray[6] = 0x30; myController.MODULE_6_OUT.ByteArray[7] = 0x30; myController.MODULE_6_OUT.ByteArray[8] = 0x32; // HI-LO Alarm myController.MODULE_6_OUT.ByteArray[9] = 0x32; // Non Latching °C myController.MODULE_6_OUT.ByteArray[10] = 0x30; // standard control myController.MODULE_6_OUT.ByteArray[11] = 0x32; // Zeichen 11 Fühler Type E Thread.Sleep(100); myController.MODULE_6_OUT.ByteArray[0] = 0x18; myController.MODULE_6_OUT.ByteArray[1] = 0x30; // Zeichen 1 myController.MODULE_6_OUT.ByteArray[2] = 0x30; myController.MODULE_6_OUT.ByteArray[3] = 0x30; myController.MODULE_6_OUT.ByteArray[4] = 0x35; myController.MODULE_6_OUT.ByteArray[5] = 0x30; myController.MODULE_6_OUT.ByteArray[6] = 0x30; myController.MODULE_6_OUT.ByteArray[7] = 0x30; myController.MODULE_6_OUT.ByteArray[8] = 0x30; // Zeichen 8 Thread.Sleep(100); myController.MODULE_6_OUT.ByteArray[0] = 0x30; // zwischenpuffer leeren Thread.Sleep(100); myController.MODULE_6_OUT.ByteArray[0] = 0x70; // zwischenpuffer leeren } public async Task<string[]> TempController_ReadTemperature() { var result = await Task<string[]>.Factory.StartNew(() => { string[] werte = ReadingTemperatures(myController); return werte; }); return result; } private static string[] ReadingTemperatures(HFI_Appl myController) { StringBuilder setpoints = new StringBuilder(); byte[] inbytes = new byte[33]; myController.MODULE_6_OUT.ByteArray[0] = 0x13; myController.MODULE_6_OUT.ByteArray[1] = 0x4C; myController.MODULE_6_OUT.ByteArray[2] = 0x30; myController.MODULE_6_OUT.ByteArray[3] = 0x54; Thread.Sleep(100); myController.MODULE_6_OUT.ByteArray[0] = 0x30; Thread.Sleep(100); for (int i = 0; i < 11; i++) { inbytes[i] = myController.MODULE_6_IN.ByteArray[i + 1]; } myController.MODULE_6_OUT.ByteArray[0] = 0x70; Thread.Sleep(100); for (int i = 11; i < 22; i++) { inbytes[i] = myController.MODULE_6_IN.ByteArray[i - 10]; } myController.MODULE_6_OUT.ByteArray[0] = 0x30; Thread.Sleep(100); for (int i = 22; i < 33; i++) { inbytes[i] = myController.MODULE_6_IN.ByteArray[i - 21]; } byte[] Temp1 = new byte[] { inbytes[0], inbytes[1], inbytes[2], inbytes[3] }; byte[] Temp2 = new byte[] { inbytes[4], inbytes[5], inbytes[6], inbytes[7] }; byte[] Temp3 = new byte[] { inbytes[8], inbytes[9], inbytes[10], inbytes[11] }; byte[] Temp4 = new byte[] { inbytes[12], inbytes[13], inbytes[14], inbytes[15] }; string s1 = Encoding.ASCII.GetString(Temp1); string s2 = Encoding.ASCII.GetString(Temp2); string s3 = Encoding.ASCII.GetString(Temp3); string s4 = Encoding.ASCII.GetString(Temp4); int TempCell1, TempCell2, TempCell3, TempCell4; Int32.TryParse(s1, out TempCell1); Int32.TryParse(s2, out TempCell2); Int32.TryParse(s3, out TempCell3); Int32.TryParse(s4, out TempCell4); return new string[] { TempCell1.ToString(), TempCell2.ToString(), TempCell3.ToString(), TempCell4.ToString() }; }
Gruß Markus
- Typ geändert Robert BreitenhoferModerator Dienstag, 22. Januar 2013 10:58 Keine Rückmeldung des Fragenstellender
Alle Antworten
-
Hallo,
ohne den Code näher zu betrachten wie wäre es mit einer Queue die Methoden annimmt und diese abarbeitet ?
siehe http://codereview.stackexchange.com/questions/6826/action-queue-in-net-3-5
-
Hallo,
danke schonmal für die Antwort.
Habe es grade mal mit dem Beispiel probiert, allerdings funktionierte dann garnichts mehr.
Ist es richtig, das ich nach diesem Beispiel jeden Methodenaufruf der auf diesen Controller zugreift in die Queueliste hinzufügen und dann die abarbeitung der Liste starten muss? Also etwa so:
private void Timer_Tick(object sender, EventArgs e) { queue.Enqueue(Timer_Aufgaben); queue.Process(); } private void Button1_Click(object sender, RoutedEventArgs e) { queue.Enqueue(Button1_Aufgaben); queue.Process(); } private void Button2_Click(object sender, RoutedEventArgs e) { queue.Enqueue(Button2_Aufgaben); queue.Process(); }
Gruß Markus
-
Hallo,
fast : Du fügst in die Queue Actions ein.
Diese Queue sollte dauerhaft von einer Schleife gepollt werden, damit du die Actions immer
dauerhaft abarbeitest oder einen Timer der alle xx Millisekunden die Queue um eine Action "befreit"
Natürlich kannst du es auch über Buttons lösen, das wäre dann aber pur Manuell ;-)
Grüße
-
Hallo,
für das abarbeiten ist doch der Aufruf
queue.Process();
zuständig, oder habe ich da was falsch interpretiert? Diesen Aufruf habe ich nun in einen Timer geschrieben.
Und das hinzufügen von Methoden in die Liste, sollte doch so sein:
queue.Enqueue(methode);
Nur das funktioniert irgendwie nicht.
Gruß Markus
-
Hi ,
du fügst zwar Methoden dazu aber nutzt diese nicht.
Du musst in einem Timer diese auch ausführen.
Also erst mit
http://msdn.microsoft.com/en-us/library/system.collections.queue.dequeue%28v=vs.100%29.aspx
rausholen und dann ausführen.
-
Hallo,
in der Klasse, die hier gezeigt wird, ist die Dequeue-Methode nicht vorhanden.
http://codereview.stackexchange.com/questions/6826/action-queue-in-net-3-5
Wie müsste diese denn hiefür aussehen, dann füge ich sie ein. Allerdings ist das gezeigte beispiel nicht so ganz vollständig scheint mir.
-
Hallo,
das ganze Projekt wird problematisch werden, da es sich ohne die beiden Controller nicht starten lässt.
Alternativ könnte ich die 3 Dateien schicken, in denen diese Arbeit getan werden soll.
Wenn das genügt schicke ich Ihnen diese zu.
Gruß Markus
-
****************************************************************************************************************
Dieser Thread wurde mangels weiterer Beteiligung ohne bestätigte Lösung abgeschlossen.
Neue Rückfragen oder Ergänzungen zu diesem Thread bleiben weiterhin möglich.
****************************************************************************************************************Robert Breitenhofer, MICROSOFT
Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.