Laden...

Extra Thread für Serielle Kommunikation, Ergebnis zurückmelden, MVVM

Erstellt von ill_son vor 6 Jahren Letzter Beitrag vor 6 Jahren 1.347 Views
I
ill_son Themenstarter:in
227 Beiträge seit 2009
vor 6 Jahren
Extra Thread für Serielle Kommunikation, Ergebnis zurückmelden, MVVM

Hallo,

ich arbeite gerade an einer Software, die per SerialPort mit einem externen Gerät kommuniziert. Da die Antwort des Geräts manchmal etwas dauert, möchte ich das ganze aus dem GUI-Thread auslagern. Weiterhin kann die Kommunikation von verschiedenen Stellen im Programm erfolgen. Damit es keine Kollisionen gibt habe ich eine Klasse geschrieben die je eine ConcurrentQueue für Kommunikationsanfragen und Antworten enthält sowie einen Thread, der die Anfragen aus der einen Queue holt, die Kommunikation durchführt und die Antworten in die andere Queue packt.

Meine Frage ist, wie bekomme ich auf MVVM-verträgliche Art die Antwort zurück zum Fragesteller (Event oder ein anderes Messaging), bzw. hat jemand eine grundsätzlich bessere Lösung für das ganze?

Grüße, Alex

Final no hay nada más

709 Beiträge seit 2008
vor 6 Jahren

Hallo,
ich habe das bei mir so implementiert, dass jede Nachricht, die gesendet wird, mit einer Nummer versehen ist, die dann auch in der Antwort auftaucht. Beim Senden wird gewartet, bis die Klasse, die die Antwortdaten in Objekte wandelt, ein Antwortpaket mit der passenden Nummer hat und dieses dann entsprechend umgewandelt zurückgegeben. Das Ganze habe ich mit async/await und 'ner TaskCompletionSource innerhalb einer Service-Klasse gemacht. Diese Service-Klasse wird dann per Dependency Injection überall dort injiziert, wo sie benötigt wird.

F
10.010 Beiträge seit 2004
vor 6 Jahren

Wenn du in die Klasse die in die Queue kommt ein Event oder Action<T> packst kannst du am Ende der Bearbeitung den Anfragesteller benachrichtigen.

W
872 Beiträge seit 2005
vor 6 Jahren

Wenn es um reines Request/Response Handling geht, dann kann man sehr einfaches und elegantes mit dem ActionBlock machen.


private void OnMessage(Response response)
        {
            lock (locker)
            {
                try
                {
                    Cache[response.PrivateKey].Post(response);
                    Cache[response.PrivateKey].Complete();
                    Cache.Remove(response.PrivateKey);
                }
                catch (Exception ex)
                {
                    Log.Error("Error in message handling:" + ex);
                }
            }
        }

        public async Task<Response> Send(Request request)
        {
            Response result = null;
            var actionBlock = new ActionBlock<Response>(message => result = message);
            lock (locker)
            {
                var key = PrivateCounter++.ToString();
                request.SetPrivate(key);
                Cache.Add(key, actionBlock);
                device.Send(request);
            }
            await actionBlock.Completion;
            return result;
        }

I
ill_son Themenstarter:in
227 Beiträge seit 2009
vor 6 Jahren

Kurzes Feedback:

ich habe in meiner Kommunikationsklasse ein Callback Action<T> implementiert, das nach jeder Kommunikation aufgerufen wird. Im MainViewModel gibt es dann eine Callbackfunktion die ja nach Typ der beantworteten Kommunikation die entsprechende Aktion ausführt.

Danke für die Hinweise und Tipps.

Grüße, und schönes Wochende,

Alex

Final no hay nada más