Benutzer mit den meisten Antworten
[UWP] Wo und Wie Initialisierung/Instanziierung SerielDevice global/by reference?

Frage
-
Hallo liebe MSDN-Community,
das ist mein erster Beitrag. Via Suche habe ich nichts zu meiner Frage gefunden (jedenfalls nichts was diese explizit beantwortet).
Meine Konstellation:
Ich habe auf meinem Raspi 3 eine UWP-App (bin ganz am Anfang der Entwicklung) laufen die via serieller Schnittstelle (Async) kommuniziert.
Mein Problem:
Ich initialisiere die Verbindung im Konstruktor der MainPage (zwecks Test und Rohbau der App), wenn ich nun auf eine andere Seite wechsle und wieder zurück auf die MainPage, wird die Verbindung erneut aufgebaut (nur, dass sie zuvor eben nicht geschlossen wurde) das führt dazu, dass kein SerialDevice verbunden werden kann. (Weil ja noch verbunden)
Meine Frage:
Wo und wie instanziiere ich die serielle Verbindung und wie mache ich diese für alle Seiten verfügbar? (Ich möchte ungern ein Singleton oder eine statische Klasse verwenden, da ich die App portabel und erweiterbar halten möchte was die Kommunikationsschnittstellen angeht - wenn das dem nicht widersprechen sollte freue ich mich auch über solche Lösungsvorschläge)
Eine Lösung ist natürlich bei jedem Seitenwechsel die Verbindung zu schließen und auf jeder Seite diese neu aufzubauen, das kommt mir aber verdächtig falsch vor :D
Falls zusätzliche Infos von Nöten sind, einfach sagen :)
Danke vorab für die Hilfe!
Falls ich was im Forum übersehen habe freue ich mich über einen Link zum Thread - in diesem Fall Sorry für die unnötige Arbeit und danke für den Link :-)
Grüße,
Johannes
Donnerstag, 5. Januar 2017 13:30
Antworten
-
Hallo Johannes,
wenn du die selbe Verbindung weiter reichen willst, dann solltest du diese in einer anderen Klassen "zwischenlagern" und immer von dort abrufen. Wenn es insgesamt nur eine Verbindung geben soll kann das auch in einer statischen Klasse erfolgen, andernfalls auch musst du die Verbindung immer mit hin- und her reichen.
Grob skizziert sieht das dann so aus:
public class ConnectionUtil : IDisposable{ public void Connect(){ //Stelle eine Verbindung her } public void Dispose(){ //Schliesse die Verbindung //Dispose wird von IDisposable vorgeschrieben und die Klasse kann somit ggf. auch in einem using/Block verwendet werden } //Nachfolgendes nur dann wenn du Singleton implementieren willst, weil es garantiert nur eine Verbindung gibt //Konstruktor private machen dass nur die Klasse selbst darauf yugreifen kann private ConnectionUtil(){} //Statische Eigenschaft anlegen public static ConnectionUtil Instance{get;} = new ConnectionUtil();
}Entweder du übergibst beim Navigieren nun immer eine Instanz der Klasse oder aber (sofern nur eine Instanz existiert) du greifst immer auf ConnectionUtil.Instance zu.
Damit es sauberer ist solltest du ganz am Ende natürlich trotzdem nicht vergessen Dispose aufzurufen.
Typisch für solche Klassen ist außerdem, dass sie noch andere Hilfsmethoden enthalten die für die Verwendung der Verbindung hilfreich/notwendig sind. So kann man diese ggf. einfach wiederverwenden.
Viele Grüße, Tom Lambert - MVP, MCC und MSP
Wozu Antworten markieren und Posts bewerten? Klicke hier
Nützliche Links: .NET Quellcode | C#/VB.NET Konverter | GitHub Forum Samples | Account bestätigen (Verify Your Account)
Ich: Webseite | Facebook | Twitter | Code Snippets | GitHub- Als Antwort markiert JojoEffect Donnerstag, 5. Januar 2017 17:59
Donnerstag, 5. Januar 2017 15:21 -
Hallo Johannes,
Singleton hat im wesentlichen den Vorteil, dass du auch Schnittstellen implementieren und das Objekt dann als solche übergeben kannst.
Bei IDisposable bringt das noch nicht all zu viel, aber gibt es ja eine andere Schnittstelle die du gebrauchen kannst.App ist auch nur eine ganz normale Klasse und unterliegt den Richtlinien von C# was Zugriffsmodifizierer etc. angeht. Von daher müsstest du wieder etwas statisches einbauen oder aber du rufst das aktuelle App-Objekt ab (geht glaube, weiß aber gerade nicht wie).
Du kannst zwar theoretisch alles in die App-Klasse packen, ich würde es jedoch trotzdem in eine eigene Klasse auslagern um alles was die Verbindung betrifft weiter abzukapseln.Die Connect-Methode meiner beispielhafte ConnectionUtil-Klasse müsstest du dann natürlich trotzdem in App aufrufen, oder je nachdem wo du zuerst die Verbindung aufbauen möchtest.
Für Dispose gilt das gleiche.Viele Grüße, Tom Lambert - MVP, MCC und MSP
Wozu Antworten markieren und Posts bewerten? Klicke hier
Nützliche Links: .NET Quellcode | C#/VB.NET Konverter | GitHub Forum Samples | Account bestätigen (Verify Your Account)
Ich: Webseite | Facebook | Twitter | Code Snippets | GitHub- Als Antwort markiert JojoEffect Donnerstag, 5. Januar 2017 17:59
Donnerstag, 5. Januar 2017 17:30
Alle Antworten
-
Hallo Johannes,
wenn du die selbe Verbindung weiter reichen willst, dann solltest du diese in einer anderen Klassen "zwischenlagern" und immer von dort abrufen. Wenn es insgesamt nur eine Verbindung geben soll kann das auch in einer statischen Klasse erfolgen, andernfalls auch musst du die Verbindung immer mit hin- und her reichen.
Grob skizziert sieht das dann so aus:
public class ConnectionUtil : IDisposable{ public void Connect(){ //Stelle eine Verbindung her } public void Dispose(){ //Schliesse die Verbindung //Dispose wird von IDisposable vorgeschrieben und die Klasse kann somit ggf. auch in einem using/Block verwendet werden } //Nachfolgendes nur dann wenn du Singleton implementieren willst, weil es garantiert nur eine Verbindung gibt //Konstruktor private machen dass nur die Klasse selbst darauf yugreifen kann private ConnectionUtil(){} //Statische Eigenschaft anlegen public static ConnectionUtil Instance{get;} = new ConnectionUtil();
}Entweder du übergibst beim Navigieren nun immer eine Instanz der Klasse oder aber (sofern nur eine Instanz existiert) du greifst immer auf ConnectionUtil.Instance zu.
Damit es sauberer ist solltest du ganz am Ende natürlich trotzdem nicht vergessen Dispose aufzurufen.
Typisch für solche Klassen ist außerdem, dass sie noch andere Hilfsmethoden enthalten die für die Verwendung der Verbindung hilfreich/notwendig sind. So kann man diese ggf. einfach wiederverwenden.
Viele Grüße, Tom Lambert - MVP, MCC und MSP
Wozu Antworten markieren und Posts bewerten? Klicke hier
Nützliche Links: .NET Quellcode | C#/VB.NET Konverter | GitHub Forum Samples | Account bestätigen (Verify Your Account)
Ich: Webseite | Facebook | Twitter | Code Snippets | GitHub- Als Antwort markiert JojoEffect Donnerstag, 5. Januar 2017 17:59
Donnerstag, 5. Januar 2017 15:21 -
Hallo Tom,
danke für die schnelle Antwort. Einen Teil meiner Frage hast du mir beantwortet, danke. Fortführende Frage zu Singleton: welchen Vorteil hat ein Singleton in meinem Anwendungsfall gegenüber einer statischen Klasse?
Was den zweiten Teil meiner Frage angeht, habe ich mich vielleicht undeutlich ausgedrückt: wo instanziiere ich ein solches Objekt? Wie unten dargestellt in der "Main()" funktioniert es leider nicht. (was entweder in der Natur der Sache liegt - und ich es nur nicht verstehe, oder weil ich einen Fehler mache.)
namespace SensoWatchApp { sealed partial class App : Application { private SerialConnection _COM; public App() { this.InitializeComponent(); this.Suspending += OnSuspending; this.COM = new SerialConnection(); Connect(); } private async void Connect() { await this.COM.OpenSerialPort(); } internal SerialConnection COM { get { return _COM; } set { _COM = value; } }
Ich kann so leider nicht aus MainPage.xaml.cs auf die in App.xaml.cs hergestellte Verbindung zugreifen. Ich dachte, dass App der "Container" für meine komplette Anwendung ist, sprich dass ich auf ein Feld von App von überall her zugreifen kann. Da scheine ich wohl was falsch verstanden zu haben!?
Viele Grüße,
Johannes
- Bearbeitet JojoEffect Donnerstag, 5. Januar 2017 17:15
Donnerstag, 5. Januar 2017 17:14 -
Hallo Johannes,
Singleton hat im wesentlichen den Vorteil, dass du auch Schnittstellen implementieren und das Objekt dann als solche übergeben kannst.
Bei IDisposable bringt das noch nicht all zu viel, aber gibt es ja eine andere Schnittstelle die du gebrauchen kannst.App ist auch nur eine ganz normale Klasse und unterliegt den Richtlinien von C# was Zugriffsmodifizierer etc. angeht. Von daher müsstest du wieder etwas statisches einbauen oder aber du rufst das aktuelle App-Objekt ab (geht glaube, weiß aber gerade nicht wie).
Du kannst zwar theoretisch alles in die App-Klasse packen, ich würde es jedoch trotzdem in eine eigene Klasse auslagern um alles was die Verbindung betrifft weiter abzukapseln.Die Connect-Methode meiner beispielhafte ConnectionUtil-Klasse müsstest du dann natürlich trotzdem in App aufrufen, oder je nachdem wo du zuerst die Verbindung aufbauen möchtest.
Für Dispose gilt das gleiche.Viele Grüße, Tom Lambert - MVP, MCC und MSP
Wozu Antworten markieren und Posts bewerten? Klicke hier
Nützliche Links: .NET Quellcode | C#/VB.NET Konverter | GitHub Forum Samples | Account bestätigen (Verify Your Account)
Ich: Webseite | Facebook | Twitter | Code Snippets | GitHub- Als Antwort markiert JojoEffect Donnerstag, 5. Januar 2017 17:59
Donnerstag, 5. Januar 2017 17:30