# TNoDave Fehlermeldung



## Human (22 Juli 2009)

Hab gerade mal ein bisschen herumgespielt und wollte mal ausprobieren, ob das mit dem Verbindungsabbruch in der neuen Version auch wirklich funktioniert.

Mit der TNoDave, die enthalten ist geht das erstmal garnicht, mein Debugger meinte, dass der letzte Fehler -1025 ist:

in der procedure TNoDaveReadThread.Execute fehlt also noch das:

```
If NoDave.LastError = -1025 then NoDave.Disconnect else
```
 
Dann:
- einmal verbinden: klappt,
- Verbindung kappen: klappt,
- nochmal verbinden: klappt
- Verbindung nochmal kappen: Klappt NICHT.

Mein Debugger meinte dazu im TNoDaveReadThread.Execute garnichts, läuft nicht. Mal geschaut, was wo der Thread erstellt wird (wird ja beim DisConnect mit FreeAndNil zerstört), in der TNoDave.DoOnConnect mal das "not Assigned(ReadThread) and" ausgeklammert, geht:


```
If (FInterval > 0) and {not Assigned(ReadThread) and} not (csDesigning in ComponentState)
    then ReadThread:=TNoDaveReadThread.Create(Self);
  If Assigned(OnConnect) then OnConnect(Self);
```
 
[EDIT]
Da ist mir gerade noch was aufgefallen:

Sollte beim Disconnect (procedure TNoDave.Disconnect) nicht zuerst der Thread beendet werden bevor man die Verbindung schließt, da kommen hin und wieder ein paar ganz komische undefinierte Zugriffsverletzungen???
[/EDIT]


----------



## afk (23 Juli 2009)

Die enthaltene Delhi-Komponente ist noch auf dem Stand von 2007. Meine aktuelle Version enthält einiges an Änderungen, die ich seitdem gemacht habe. Die von Dir erwähnten Änderungen für die neueste libnodave-Version muß ich aber noch nachziehen, sobald ich Zeit habe. 

Ich werde mich mit Zottel in Verbindung setzen, sobald ich dammit fertig bin, damit er das dann auch auf SourceForge veröffentlicht.


Gruß Axel


----------



## Human (23 Juli 2009)

Kannst du vielleicht vorab schon sagen welche Änderungen das sind?


----------



## afk (24 Juli 2009)

Ich hab mir das Ganze jetzt mal genauer angeschaut:


Human schrieb:


> Hab gerade mal ein bisschen herumgespielt und wollte mal ausprobieren, ob das mit dem Verbindungsabbruch in der neuen Version auch wirklich funktioniert.
> 
> Mit der TNoDave, die enthalten ist geht das erstmal garnicht, mein Debugger meinte, dass der letzte Fehler -1025 ist:
> 
> ...


Die Funktion mit dem Keep-Alive hatte ich in meiner Komponente (interner Stand von mir) bereits implementiert, bevor Zottel das direkt in libnodave eingabaut hat. Ich muß jetzt erst mal überprüfen, ob sich das miteinander verträgt.



Human schrieb:


> Dann:
> - einmal verbinden: klappt,
> - Verbindung kappen: klappt,
> - nochmal verbinden: klappt
> ...


Beim Disconnect wird darauf gewartet, und zwar auch schon in der Version, die bei libnodave 0.8.4.4 dabei war. Am Ende von Disconnect wird zuerst Active auf False gesetzt, und dann DoOnDisconnect aufgerufen. In DoOnDisconnect wird per ReadThread.WaitFor darauf gewartet, bis sich der Thread beendet hat, der Speicher des Thread freigegeben, und danach noch der OnDisconnect-Event ausgelöst. In der Execute des ReadThread wiederum wird die Active-Eigenschaft der Komponente als Abbruch-Bedingung für die Leseschleife verwendet, was zur Folge hat, daß der Thread sich selbst beendet, nachdem Active auf False gesetzt wurde (was ja schon vor Aufruf der DoOnDisconnect gemacht wird).

Das Einzige, was hier noch schief laufen kann, ist, daß die Methode Disconnect aufgerufen wird, darin dann Active auf false gesetzt wird, DoOnDisconnect auf das Ende des Threads wartet (was etwas dauern kann, entweder durch einen der Synchronize-Aufrufe, oder wenn libnodave gerade auf Antwort von der SPS oder dem TCP/IP-Stack wartet), und in dem Augenblick ein weiterer Thread des Anwenderprogramms wieder einen Connect initiiert. Dann existiert dieser Thread noch (beendet sich aber kurz danach und wird dann in DoOnDisconnect entfernt, bleibt also nix "hängen"), und dementsprechend wird in DoOnConnect dann eben kein ReadThread erzeugt. Innerhalb der Komponente kann ich diesen Fall zwar nicht abfangen, aber mit dem OnDisconnect-Event kann das ganz einfach im Anwenderprogramm abgefangen werden, indem ein erneuter Connect erst dann zugelassen wird, nachdem OnDisconnect ausgelöst wurde.

Ich will hier aber nochmals erwähnen, daß der ReadThread grundsätzlich sowieso nur für die quick and dirty - Lösung da ist (siehe auch hier).



Human schrieb:


> Kannst du vielleicht vorab schon sagen welche Änderungen das sind?




```
// 16.03.2007 10:32:26 [C:\Programme\Borland\BDS\User\GsfExperts\NoDave\NoDaveComponent.pas]
//     Bugfix in TNoDave.DoReadBytes
// 16.03.2007 11:48:24 [C:\Programme\Borland\BDS\User\GsfExperts\NoDave\NoDaveComponent.pas]
//     Implemented TNoDave.GetSInt and TNoDave.WriteSInt as suggested by J. Lachmann.
// 04.04.2007 09:58:34 [C:\Programme\Borland\BDS\User\GsfExperts\NoDave\NoDaveComponent.pas]
//     ConnectPending removed and replaced with use of LockNoDave in TNoDave.DoConnect
// 31.05.2007 10:10:50 [C:\Programme\Borland\BDS\User\GsfExperts\NoDave\NoDaveComponent.pas]
//     Bugfix in TNoDave.DoWriteBytes. Thanks to Davide Nardella.
// 27.08.2007 16:05:18 [C:\Programme\Borland\BDS\User\GsfExperts\NoDave\NoDaveComponent.pas]
//     In Get...-Methods the values of the properties BufOffs and BufLen are used now,
//     if not defined in the method-parameters with the same name.
//     Thanks to Philippe D'Hont for the hint.
// 26.03.2009 13:41:38 [C:\Daten\Delphi 2006\Komponenten\GsfExperts\NoDave\NoDaveComponent.pas]
//     TCP KeepAlive functionality used for all TCP/IP protocols.
// 27.04.2009 10:55:22 [C:\Daten\Delphi 2006\Komponenten\GsfExperts\NoDave\NoDaveComponent.pas]
//     Call to DoOnRead removed from Method ReadBytes to avoid double call of OnRead.
//     Thanks to Nils Erichson for the hint.
// 03.05.2009 15:32:55 [C:\Daten\Delphi 2006\Komponenten\GsfExperts\NoDave\NoDaveComponent.pas]
//     Usage of AnsiString, AnsiChar and PAnsiChar instead of String, Char and PChar
//     for compatibility with Delphi 2009. Thanks to user Lazarus at sps-forum.de.
// 04.05.2009 08:45:17 [C:\Daten\Delphi 2006\Komponenten\GsfExperts\NoDave\NoDaveComponent.pas]
//     Methods TNoDave.GetString and TNoDaveWriteString implemented to read or write
//     a string in PLC format. Thanks to Marc Engbarth for the proposal.
```
Außerdem hab ich irgendwann auch noch ein Property für die Parity vom COM-Port eingebaut (für S5-Kommunikation), hab aber vergessen das zu dokumentieren.


Gruß Axel


----------

