Backgroundworker oder Async für zeitkritische Anwendungen?

  • VB.NET

Es gibt 31 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Backgroundworker oder Async für zeitkritische Anwendungen?

    Hallo zusammen,

    ich habe den Auftrag eine bestehende Anwendung in zu erweitern. Es geht um eine Anwendung für eine Anlage durch die diverse Werkstücke laufen, auf welche ein Aufdruck aufgebracht wird. Der Drucker dazu wird durch den Leitrechner, bzw durch das Programm angesteuert. Die Erweiterung besteht daraus, eine Auftragsnummer in eine SQL-Tabelle zu schreiben(Rückmeldung). Ganz grob gesagt gibt es zwei Subs (HandleDrucker und HandleRückmeldung).

    Diese beiden Subs werden zyklisch durch einen Timer (Intervall: 1s) aufgerufen.
    Das Problem besteht darin, dass HandleDrucker in der Ausführung ca. 5s benötigt und HandleRückmeldung ca. 1s.
    Die Werkstücke kommen gerade so in einem Abstand von ca. 6s an den entsprechenden Punkten in der Anlage an. Nun besteht seit der Erweiterung, das Problem, dass der Drucker in unregelmäßigen Abständen Daten verschluckt und der Aufdruck nicht immer zum Werkstück passt.
    Die HandleDrucker-Sub möchte ich nicht ändern, da diese schon seit vielen Jahren funktioniert hat und durch einen externen Entwickler geschrieben wurde. Im Endeffekt wird darin ein Handshake mit der Steuerung (SPS) abgearbeitet, die Daten werden von einem SQL-Server geholt, aufbereitet und per TCP/IP an den Drucker geschickt.

    Meine Idee wäre also nun, die HandleRückmeldung in einen Backgroundworker zu schieben. Würde mir das prinzipiell einen zeitlichen Vorteil verschaffen? Also würde er wirklich parallel zur restlichen Anwendung laufen?
    Ist vielleicht auch etwas Anderes ratsam (Async/Await, Multithreading)?

    Zum Backgroundworker hätte ich auch noch eine weitere Frage: Wenn er läuft, und es würde in dieser Zeit ein weiteres Werkstück eintreffen, welches rückgemeldet werden soll, wird es dann "verschluckt" oder müsste ich für diesen Fall einen weiteren Backgroundworker vorhalten, um den Job abzuarbeiten?

    Was noch interessant sein könnte: verwendet wird Net-Framework 2.0

    Ich würde also nur gern wissen, was in einem solchen Fall empfehlenswert ist. Die Theorie zur jeweiligen Technik werde ich mir dann selbst erarbeiten.

    Schon einmal Danke an der Stelle für Rückmeldungen.
    Backgroundworker ist nicht mehr up to date.
    Async, Await sind demnach die logische Alternative.

    In dem Fall solltest Du für jede Rückmeldung einen Async Prozess anstossen.

    Der Vorschlag von Yanbel ist auch nicht schlecht.
    Kunst kommt von können und nicht von wollen, sonst hieße es Wunst!
    @RiLo Zunächst einmal musst Du sicherstellen, dass die Prozedur HandleDrucker nicht aufgerufen werden kann, so lange noch gedruckt wird.
    Siehe dazu SyncLock: docs.microsoft.com/de-de/dotne…ements/synclock-statement
    Ein Backgroundworker hat die (eine) Instanz, die Du erstellst.
    Async-Await kannst Du in einer For-Schleife aufrufen und alles läuft.
    Lass also den Backgroundworker im Museum.
    =====
    Die SPS sollte ein Trigger-Signal bereitstellen, dessen Anliegen Du durch Polling feststellen kannst.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RiLo schrieb:

    @ Yanbel: Hättest du da ein Beispiel für mich? Events müsste bei mir eigentlich die SPS werfen.


    Schwierig, da aus der Problemstellung nicht eindeutig hervorgeht, welcher Sub hier auf welchen reagiert. Und was der Sub HandleRückmeldung eigentlich genau tut. Vielleicht noch ein paar mehr Infos zum Programmablauf.


    Ein Computer wird das tun, was du programmierst - nicht das, was du willst.

    RiLo schrieb:

    HandleRückmeldung in einen Backgroundworker zu schieben. Würde mir das prinzipiell einen zeitlichen Vorteil verschaffen? Also würde er wirklich parallel zur restlichen Anwendung laufen?
    jo, entweder Backgroundworker, aber besser wäre Async.
    Ob da nun ein Eventhandling iwas verbessern würde stelle ich infrage.

    Ansonsten habt ihr vlt. einen vermurksten Sql-Zugriff.
    Insbes. die Rückmeldung hat ja kein Datenvolumen - das sollte nicht mehr als 100ms dauern.
    Aufeinander reagieren die beiden eigentlich nicht. Ich versuche es kurz zu beschreiben, ohne allzu tief ins Detail zu gehen:

    Timer ruft Sub Zyklus() auf

    in Sub Zyklus()
    HandleDrucker()
    HandleRückmeldung()
    End Sub

    in Sub HandleRückmeldung()
    Hole Wert aus SPS
    If Wert<>0 then schreibe Wert in sql-Tabelle
    Schreibe in SPS Wert=0
    End Sub

    @ErfinderDesRades: Das Zeitintensive an HandleRückmeldung() ist der SPS-Zugriff. Die 100ms für den SQL-Befehl kommen ziemlich gut hin.
    @Rod: das Problem ist scheinbar die Zeit für die Ausführung von HandleDrucker
    Deswegen möchte ich ja die Sub HandleRückmeldung parallel dazu laufen lassen, da keiner auf den anderen warten muss. Mir geht es nur darum zu erfahren, welche von den genannten Methoden in meinem Fall die Bessere wäre.
    Ein Trigger-Signal gibt es von der SPS nicht. Ist ein etwas älteres Modell (keine Siemens-SPS).
    Sind die Daten für den Druck vor dem Drucktrigger beriets da oder werden die durch den Trigger (Bauteil da) erst angefordert?

    Die Dauer der SPS Abfrage ist auf jeden Fall zu lang.
    Erfolgt die Abfrage über Profibus, Netwerk, ...?
    Kunst kommt von können und nicht von wollen, sonst hieße es Wunst!
    na das ist einfach:

    VB.NET-Quellcode

    1. Async Sub Zyklus()
    2. HandleDrucker()
    3. Await Task.Run(Addressof HandleRückmeldung)
    4. End Sub
    5. Sub HandleRückmeldung()
    6. Hole Wert aus SPS
    7. If Wert<>0 then schreibe Wert in sql-Tabelle
    8. Schreibe in SPS Wert=0
    9. End Sub

    Aber wie andere auch schon gesagt: kommt mir komisch vor, dass ein SPS (was immer das sein mag) anzusprechen so lange dauern sollte.
    Andererseits kann man aber auch gelten lassen: Uralt-Code, den niemand mehr versteht, geniesst Bestandsschutz.
    @xmise: die Daten für den Druck werden erst durch den Trigger geholt.
    die Abfrage erfolgt über eine Applicom (PCI)-Karte mit dem Ethway-Protokoll (Telemecanique Eigenentwicklung, etwas älter)

    @ErfinderDesRades: Würde Zyklus() dann auf das Abarbeiten von HandleRückmeldung() warten oder verstehe ich das falsch? Habe mich bisher noch nicht weiter mit Async auseinandergesetzt.

    RiLo schrieb:

    HandleDrucker
    Was genau passiert da?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @Rod: Die Prozedur liest aus der SPS ob ein neuer Auftrag benötigt wird, sucht aus einer sql-datenbank die passenden Werte zum Auftrag raus und schickt diese an den Drucker. Danach wird in die SPS geschrieben, dass der Drucker Daten bekommen hat. (stark vereinfacht)

    @ErfinderDesRades: Dann bin ich doch aber an demselben Punkt wie vorher, oder läuft HandleRückmeldung dann tatsächlich parallel zu HandleDrucker? Mir fehlt irgendwie so ein Schlagwort bei dieser Art der parallelen Verarbeitung. Sowas wie bei Backgroundworker DoWork
    @RiLo Zunächst sehe ich, dass erst dann (also bei jedem ca. 5. Takt) der Drucker bemüht werden muss.
    Du bemühst ihn aber jede Sekunde.
    Also:

    RodFromGermany schrieb:

    Was genau passiert da?
    Oder ganz einfach:
    Was passiert, wenn ein Druckauftrag läuft und HandleDrucker aufgerufen wird?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!