Projekt zyklisches Senden und Empfangen von Http Daten
- VB.NET
- .NET (FX) 4.5–4.8
Sie verwenden einen veralteten Browser (%browser%) mit Sicherheitsschwachstellen und können nicht alle Funktionen dieser Webseite nutzen.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Es gibt 25 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.
-
-
guggemol dies:
VB.NET-Quellcode
- Imports System.IO
- Imports System.Net
- Public Class Bacnet
- Public Property Id As String
- Public Property Pid As String
- Public Property Plz As Integer
- Public Property Ort As String
- Public Property Time As Integer
- Private WrTimeout As Integer = 1000 'Angaben in ms
- Private SrTimeout As Integer = 1000 'Angaben in ms
- Private _Data As String
- Private _EMessage As String
- Private _RMessage As String
- Public ReadOnly Property Data() As String
- Get
- Return _Data
- End Get
- End Property
- Public ReadOnly Property EMessage As String
- Get
- Return _EMessage
- End Get
- End Property
- Public ReadOnly Property RMessage As String
- Get
- Return _RMessage
- End Get
- End Property
- Public Sub WdVorhersage()
- Dim Url = "http://api.openweathermap.org/data/2.5/forecast?q=" & Ort & ",DE&mode=xml&appid=" & Pid & "&units=metric&lang=de"
- Dim Request = WebRequest.Create(Url)
- Request.Timeout = WrTimeout
- Using Response = Request.GetResponse(), Reader = New StreamReader(Response.GetResponseStream())
- _Data = Reader.ReadToEnd()
- End Using
- End Sub
- End Class
Beachte die Namenskonvention mit_
-Prefix für private Felder. Public Properties sollten keinen Prefix haben, schon garnetP
- da fängt man ja an zu stottern wenn man das liest
Beachte auch den UsingBlock.
Und Initialisierungen wieWrTimeout = 1000
sollen nur einmal ausgeführt werden - nicht jedesmal wenn die Klasse was tun soll.
Beachte auch, dass die Time-Klasse verschwunden ist - dassis Absicht.
Und wenn du Visual Studio - Empfohlene Einstellungen richtig beherzigt hast, brauchst du nichtOption Strict On
über jede Datei zu schreiben.
Wenn du es aber nicht richtig beherzigt hast, solltest du es doch richtig beherzigen.
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()
-
Ja traumhaft. Vielen, vielen Dank.
Das mit Using ist mir das erste Mal in Verbindung mit XML-Verarbeitung bekannt geworden. Da muss ich noch den Vorteil erlesen.
Viel gelernt...Danke. Ich werde mal den Timer nun noch einbasteln.
das mit Strict On hatte ich kurzfristig aufgrund der Folgenden Aussage getätigt:
Daher empfehle ich, für jede Datei händisch die Deppen-Einstellungen wieder zu aktivieren, indem man am Anfang jeder Datei hinschreibt:
werde es mir nochmal in Gänze zu Gemüte führen
ohne Try/Catch kann EMessage auch raus.
-
Jo, das mit dem händisch ist ein Zwischen-Schritt auf das Ziel zu, der nützlich ist, um bei viel Code auf die Grundeinstellungen zu migrieren.
Nach der Migration ist Strict On ja eine Projekt-Eigenschaft, und braucht nicht weiter in jeder Datei notiert zu sein (schadet aber auch nicht, irritiert nur Korintenkacker wie mich).
Der Using-Block hat was mit dem Dispose-Pattern ( <- Google-Stichwort) zu tun - es ist eine kürzer und sicherer, als wenn man für jedes disposable Objekt .Dispose aufruft. Wie gezeigt, kann man mehrere Objekte in derselben Using-Deklaration instanzieren - das führt zu knappen, übersichtlichen, wasserdichten Code.
ja - immer alles rausschmeissen, was raus kann. Aufgeräumten Code lesen ist fast ein Vergnügen,
-
So melde mich zurück: Ich habe versucht Informationen zu dem angesprochenen Dispose-Pattern zu bekommen und teilweise auch einige Infos bekommen. Nur ich bezweifle, dass ich es verstanden habe. Es geht wohl schlussendlich um Ressourcenfreigabe, die man vorher belegt. Dann gibt es verwalteter Speicher und nicht verwalteter Speicher - einen Typ muss man explizit freigeben und bei dem Anderen nicht. Da ich in deinem Codevorschlag keine Erwähnung von Disposable o.Ä. finde, gehe ich davon aus, dass man es nicht explizit freigeben muss oder leitet man die Freigabe mit dem Using-Block ein?!
Für einen Fachinformatiker ist das vermutlich einfach, aber ich tue mich da schwer. Fakt ist, dass ich im Debug-Modus sehe, dass der Speicher freigegeben wird.
Wieso hast du die Anweisungen nicht mit im Using-Block? MSDN hat es ihren Beispielen überall enthalten.
In dem Zuge habe ich an dem Projekt weitergearbeitet und versucht das USING mit meiner XML-Auswertung zu paaren (versucht Dispose anzuwenden) und noch ein paar Anpassungen durchgeführt. Ich werde das XML nochmal umarbeiten. Aus der PHP-Sprache kenne ich Switch/Case-Anweisungen. Ich vermute, dass es solch Technik auch bei VB.net gibt und mir sagt mein Gefühl, dass das die bessere Variante ist. Natürlich bin ich für weitere Vorschläge offen.
Zusätzlich bin ich deiner Empfehlung gefolgt und habe den Timer als Form eingefügt und das Tick-Event mit auf den Handler vom Button gehangen. Kann man das so machen oder ist es nicht elegant, doof ?
Irgendwie habe ich noch das Gefühl, dass das Kompilieren und Verwenden auf einen anderen Rechner noch Probleme bereiten wird.
Abschließend möchte ich mich für die Geduld, Ausdauer und die Hilfe nochmals herzlichst bedanken und den Code anhängen.
bacnet.vb
Spoiler anzeigen VB.NET-Quellcode
- Imports System
- Imports System.IO
- Imports System.Net
- Imports Inneasoft.BACnet
- Imports System.Xml
- Public Class Bacnet
- Public Property Id As String
- Public Property Pid As String
- Public Property Plz As Integer
- Public Property Ort As String
- Private _LastTime As String
- Private _AT As String
- Private _Data As String
- Private _Message As String
- Private _WrTimeout As Integer = 1000 'Angaben in ms
- Private Request As WebRequest
- Private Response As WebResponse
- Private Stream As Stream
- Private Reader As StreamReader
- Public ReadOnly Property Data() As String
- Get
- Return _Data
- End Get
- End Property
- Public ReadOnly Property Message As String
- Get
- Return _Message
- End Get
- End Property
- Public ReadOnly Property AT As String
- Get
- Return _AT
- End Get
- End Property
- Public ReadOnly Property LastTime As String
- Get
- Return _LastTime
- End Get
- End Property
- Public Sub WdAktuell()
- Dim Url = "http://api.openweathermap.org/data/2.5/weather?q=" & Ort & ",DE&mode=xml&appid=" & Pid & "&units=metric&lang=de"
- 'Instanzieren einer Verbindung
- Request = WebRequest.Create(Url)
- Request.Timeout = _WrTimeout
- Using Response = Request.GetResponse()
- Reader = New StreamReader(Response.GetResponseStream())
- _Data = Reader.ReadToEnd()
- If Reader.EndOfStream = True Then
- If Data.Length > 1 Then
- _Message = " Daten erfolgreich empfangen!"
- End If
- End If
- Reader.Close()
- Response.Close()
- End Using
- XMLReader()
- End Sub
- Private Sub XMLReader()
- Using XmlReadSystem As XmlReader = System.Xml.XmlReader.Create(New StringReader(Data))
- XmlReadSystem.ReadToDescendant("temperature")
- XmlReadSystem.MoveToAttribute(0)
- _AT = XmlReadSystem.Value
- XmlReadSystem.ReadToNextSibling("lastupdate")
- XmlReadSystem.MoveToAttribute(0)
- _LastTime = Convert.ToDateTime(XmlReadSystem.Value).ToString
- XmlReadSystem.Close()
- End Using
- End Sub
- End Class
AWB.vb
Spoiler anzeigen VB.NET-Quellcode
- Imports System
- Imports System.IO
- Imports System.Net
- Imports System.Timers
- Imports Inneasoft.BACnet
- Public Class AWB
- Private VarTimer As Integer
- Private Wetter As New Bacnet
- Private RohWerte As String
- Private IsOnline As Boolean
- Public Sub New()
- ' Dieser Aufruf ist für den Designer erforderlich.
- InitializeComponent()
- End Sub
- Private Sub btnXml_Click(sender As Object, e As EventArgs) Handles btnXml.Click
- MessageBox.Show(RohWerte, "XML-Rohdaten", MessageBoxButtons.OK)
- End Sub
- Private Sub btnInfo_Click(sender As Object, e As EventArgs) Handles btnInfo.Click
- Infos.ShowDialog()
- End Sub
- Private Sub btnBacstart_Click(sender As Object, e As EventArgs) Handles btnBacstart.Click, Timer.Tick
- btnBacstart.Enabled = False
- btnBacStop.Enabled = True
- Timer.Enabled = True
- VarTimer = Convert.ToInt16(tbAktZeit.Text) * 60 * 1000
- If VarTimer <= 10000 Then
- Exit Sub
- Else
- tbLastTime.Text = System.DateTime.Now.ToString
- Wetterinstanz()
- If IsOnline = True Then
- Else
- Bacnetserver()
- End If
- End If
- End Sub
- Private Sub btnBacStop_Click(sender As Object, e As EventArgs) Handles btnBacStop.Click
- BACnetAPI.Uninitialize()
- Timer.Enabled = False
- RohWerte = Nothing
- btnBacstart.Enabled = True
- btnBacStop.Enabled = False
- End Sub
- Private Sub Wetterinstanz()
- Wetter.Pid = tbPid.Text
- Wetter.Ort = tbOrt.Text
- Wetter.WdAktuell()
- If String.IsNullOrEmpty(Wetter.Message) Then
- btnXml.Enabled = False
- Else
- tsStatus.Text = Wetter.Message
- tsStatus.ForeColor = Color.Lime
- btnXml.Enabled = True
- End If
- tbAt.Text = Wetter.AT
- tbLastAkt.Text = Wetter.LastTime
- RohWerte = Wetter.Data
- End Sub
- Private Sub Bacnetserver()
- Dim Server As New BACnetServerDevice
- Dim AV1 As BACnetServerObject
- BACnetSettings.Port = CType(tbPort.Text, Integer)
- Server.AddObject(New BACnetServerAnalogValue(1, "Aussentemperatur"))
- Server.Id = CType(tbBid.Text, Integer)
- Server.Name = tbBn.Text
- BACnetAPI.Initialize()
- BACnetAPI.SetServerDevice(Server)
- IsOnline = BACnetAPI.IsInitialized
- AV1 = Server.GetObject(BACnetObjectType.ANALOG_VALUE, 1)
- AV1.Value = Wetter.AT
- AV1.Description = "aktuelle Aussentemperatur"
- End Sub
- End Class
Welchen Unterschied gibt es zwischen der CType-Methode und der Convert.To-Methode? -
Mir scheint, du hast dich mit zuvielen Details belastet, und dabei die goldenen Regeln nicht mitbekommen:
- Es gibt Datentypen, deren Objekt-Instanzen der GarbageCollector nicht sauber aufräumen kann - diese Objekte müssen explizit aufgeräumt werden. (Das Gefasel von verwaltet / nicht verwaltet habich auch nicht sicher verstanden - evtl. bedeutet das auch nichts anderes, als das hier gesagte: kanner aufräumen oder nicht)
- Solche Datentypen sollten
IDisposable
implementieren, denn der Aufruf.Dispose()
ist ganz allgemein der Aufruf des expliziten Aufräumens - Ob ein Datentyp
IDisposable
implementiert, kannste im ObjectBrowser ( <- folge dem Link!! ) nachgucken. - Wenn dem so ist, ist bei Objekten dieses Datentyps dringend geraten, sie nach Verwendung zu disposen.
- Disposen kann man diese Objekte durch Aufruf von
.Dispose()
, aber eleganter und sicherer ist derUsing
-Block.
Fahrstuhllicht schrieb:
Wieso hast du die.Closed
-Anweisungen nicht mit im Using-Block? MSDN hat es ihren Beispielen überall enthalten.
Beachte: MSDN-CodeBeispiele sind zwar nie falsch, aber in vielen vielen Fällen sind sie weit davon entfernt, gut zu sein.
Also was du da findest, funktioniert zwar, und man kann Funktionsweisen daraus lernen - es ist aber meist (wage ich zu behaupten) unnötig umständlich.
Oder anders: Für Copy&Paste ist MSDN keine wirklich gute Quelle.
Abschliessend noch Genörgel wegen Benamung - weisst ja:Nomen est Omen!
WdAktuell()
ist kein Name für eine Methode (Es ist ühaupt kein Name - "WdAktuell" - was soll das sein, ein "WdAktuell"??). Eine Methode tut etwas, und soll so heissen wie was sie tut - hier scheint mirLoadCurrentWeatherData()
oder sowas angemessen, denn wenn ich recht verstehe lädt die Methode aktuelle Wetter-Daten und hinterlegt sie der Data-Property.
Ganz ähnlich der NameXmlReader()
. "XmlReader" ist keine Tätigkeit, sondern XmlReader ist eine Klasse des Frameworks. Keine gute Idee, eine Tätigkeit so zu benennen - da kommt man im Leben nicht drauf, dass das eine Methode ist, die Temperatur und LastUpdate aus der Data-Property extrahiert und als Properties verfügbar macht.
Ich würde die MethodeProcessData()
nennen, denn das ist was sie tut: Sie verarbeitet (engl: "to process") die in Data liegenden Daten.
Das AWB ist mir zu umfangreich, ums zu behühnern. Nur soweit:
"AWB" - was soll das sein? Lässt sich kein Name dafür finden, den man auch versteht?
Und bei Forms präferiere ich einen Prefix zu vergeben, etwafrmWeatherApp
, oder auch einfachfrmMain
oder sowas.
Dann weiss man wo der Code steht, und ein Form ist ein sehr spezieller und sehr reichhaltiger Code-Kontext - für den Leser unerlässlich, das zu wissen.Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()
- Es gibt Datentypen, deren Objekt-Instanzen der GarbageCollector nicht sauber aufräumen kann - diese Objekte müssen explizit aufgeräumt werden. (Das Gefasel von verwaltet / nicht verwaltet habich auch nicht sicher verstanden - evtl. bedeutet das auch nichts anderes, als das hier gesagte: kanner aufräumen oder nicht)
-
Benutzer online 1
1 Besucher
-
Ähnliche Themen
-
4 Benutzer haben hier geschrieben
- Fahrstuhllicht (13)
- ErfinderDesRades (7)
- RodFromGermany (5)
- mrMo (1)