Ich habe versucht, ein Multicast-Empfänger-Programm zu entwickeln und Socket-Initialisierung wurde wie folgt durchgeführt:
%Vor%Wenn mein PC nicht mit einem Netzwerk verbunden ist, hat die SetSocketOption-Methode eine Ausnahme ausgelöst und selbst nachdem das Netzwerk verbunden wurde, Ich konnte keine Daten empfangen, da die Socket-Optionen nicht festgelegt sind.
Um dies zu vermeiden, habe ich einen Thread benutzt, der im Hintergrund läuft für die Netzwerkverfügbarkeit und sobald das Netzwerk verfügbar ist, legt es die Socket-Optionen fest.
Es funktioniert in einigen PCs, aber in einigen anderen, NetworkInterface.GetIsNetworkAvailable()
hat True zurückgegeben, bevor das Netzwerk verbunden wurde
(während das Netzwerk identifiziert wurde).
Um sicherzustellen, dass Socket-Optionen gesetzt sind, habe ich eine bool
Variable sockOptnSet
verwendet
welches als eingestellt ist
true
, wenn alle Anweisungen im try-Block wie in der Methode public void SetSocketOptions()
ausgeführt werden
Dieses Programm funktioniert gut in allen PCs, die ich ausprobiert habe, aber ich bin mir nicht sicher, wie sehr ich darauf vertrauen kann, dass das funktioniert.
Meine Fragen sind:
1) Ist das eine gute Praxis?
2) Wenn nicht, was sind mögliche Fehler oder Probleme? Und wie kann ich es besser umsetzen?
Ist das eine gute Übung?
Nein, keine gute Übung. Die meisten Ausnahmen, einschließlich Ihrer ersten, fallen in die Kategorie ärger Ausnahmen. Software soll funktionieren, funktionierte gut, wenn Sie es getestet haben, aber nicht auf dem Computer des Benutzers. Etwas ist schiefgelaufen, aber du weißt nicht was und es gibt nichts Sinnvolles, was du dagegen tun kannst. Der Versuch, das Programm am Laufen zu halten, ist nicht sinnvoll, es kann nicht die Aufgabe erfüllen, die es ausführen soll. In Ihrem Fall gibt es keine Hoffnung, dass der Socket jemals Daten empfangen wird, wenn kein Netzwerk vorhanden ist. Und wie du herausgefunden hast, gibt es nur Probleme, wenn du versuchst, das Problem zu umgehen. Das ist normal.
Wenn dies eine schlechte Übung ist, wie kann ich sie besser umsetzen?
Sie brauchen Hilfe von einem Menschen. Der Benutzer muss den Computer einrichten, um eine funktionierende Netzwerkverbindung bereitzustellen. Dies erfordert eine Benutzerschnittstelle, Sie müssen eine Möglichkeit haben, einem Menschen zu sagen, was er tun muss, um Ihr Problem zu lösen. Sie können das so kompliziert oder so einfach machen, wie Sie es wünschen. Nur eine Fehlermeldung, eine wörtliche Kopie der Exception.Message kann genug sein. Das Schreiben eines Ereignishandlers für das AppDomain.CurrentDomain.UnhandledException-Ereignis ist eine sehr gute (und erforderliche) Strategie. Microsoft hat enorme Anstrengungen unternommen, um Ausnahmemeldungen so klar und hilfreich wie möglich zu machen. Sie können sogar in der Muttersprache des Benutzers für Sie lokalisiert werden. Selbst wenn die Ausnahmebedingungsnachricht irritiert, gibt eine schnelle Google-Abfrage für den Nachrichtentext Hunderte von Treffern zurück. Mit diesem Event-Handler müssen Sie nichts etwas tun. Ihr Programm wird automatisch beendet und Ihr Benutzer weiß, was zu tun ist.
Sie können es auf jeden Fall komplizierter machen, Sie haben festgestellt, dass SetSocketOption () wahrscheinlich scheitert, sobald das Netzwerk verfügbar wird, aber funktioniert, wenn Sie lange genug warten. Das ist also eine Fehlerbedingung, die Sie umgehen können , indem Sie nur lange genug warten. Ob Sie den Code schreiben sollten, um damit umzugehen, müssen Sie selbst entscheiden. Es ist etwas, das Sie schreiben, wenn Sie genügend Erfahrung mit der Art und Weise haben, wie sich Ihr Programm verhält, Sie schreiben es nie im Voraus. In der Regel als Ergebnis von Feedback von den Benutzern Ihres Programms.
Einige gute Ratschläge in den Kommentaren, lassen Sie 'erweitern.
Erstens würde ich all diesen Socket-Code in seine eigene Klasse außerhalb des Formulars schreiben. Dies macht es zu einer eigenen Entität und semantisch leichter zu verstehen. Diese Klasse könnte eine Eigenschaft Initialised
haben, die anfänglich auf false
gesetzt ist. Das erste, was Sie in Ihrem Formular tun, ist eine Initialise
-Methode für diese Klasse aufzurufen, die Socket-Optionen zu setzen versucht und die relevanten Ausnahmen abfängt, wenn das Netzwerk nicht verfügbar ist. Wenn verfügbar ist, setzen wir unsere Eigenschaft Initialised
auf true
.
Wenn nicht verfügbar, setzen wir ein einzelnes Timeout (siehe System.Threading.Timer
), das diese gleiche -Funktion (möglicherweise mit einer Wiederholungsanzahl) nach 'x' Sekunden aufruft. Wir werden uns wieder in dieser Initialise
-Funktion wiederfinden, vielleicht mit einer Wiederholungszählung, die am Anfang erwähnt wurde. Noch einmal, wenn es verfügbar ist, sind wir gut - wenn nicht, setzen Sie den Timer erneut. Schließlich, nach 'x' Versuchen, wenn wir nicht initialisiert sind, können wir eine Ausnahme auslösen oder eine andere Fehlereigenschaft setzen, um anzuzeigen, dass wir nicht fortfahren können.
Ihre Form
-Klasse kann periodisch prüfen (oder sich an einem Ereignis anmelden), um festzustellen, ob der Socket jetzt für die Kommunikation bereit ist. Im Falle eines Fehlers können Sie elegant beenden oder, weil unsere Klasse nett und abstrahiert ist, versuchen, den gesamten Prozess erneut zu starten.