# C#, NDde - Client baut Verbindung nicht richtig ab



## vierlagig (28 April 2011)

habe einen DDE Client mit C# zusammengeklickt.

Hilfsbibliothek: NDde [ http://ndde.codeplex.com/ ] (sonst gibts ja kaum was brauchbares  )
Wirtsystem: Win2K (also max. *.net 2.0* mgl.)

Ablauf:

Verbindung aufbauen:


```
*
public bool connect(string _sService, string _sTopic)
        {
            try
            {
                gDdeClient = new DdeClient(_sService, _sTopic, this);
                gDdeClient.Disconnected += gDdeClient_Disconnected;
                gDdeClient.Connect();
                return true;
            }
            catch (Exception ex)
            {
                gsError = ex.Message;
                return false;
            }
        }
```

überwachung hinzufügen:


```
*
        public bool advise(string _AsItem, int _iFormat, bool _xHot, int _iTimeOut, bool _xAdd)
        {
            try
            {   
                gDdeClient.StartAdvise(_AsItem, _iFormat, _xHot, _iTimeOut); 
                if(_xAdd)                    
                    gDdeClient.Advise += gDdeClient_Advise;
                return true;
            }
            catch (Exception ex)
            {
                gsError = ex.Message;
                return false;
            }
        }
```

der Event gDdeClient_Advise funktioniert auch...


ABER das trennen der Verbindung bei _Disconnect_-Wunsch oder schließen des Clients mit:


```
*
gDdeClient.Disconnect();
```

funktioniert nicht. ich sehe per netstat immer noch die offene Verdindung (Status: HERGESTELLT), auch nach mehreren Minuten noch.

auch folgendes führt nicht zum Erfolg:


```
*
foreach (string _sItem in gLisItems)
                    {
                        gDdeClient.StopAdvise(_sItem,60000);
                        displayTextBox.Text = displayTextBox.Text + Environment.NewLine + _sItem + "disconnected";                        
                    }                    
                    gDdeClient.Disconnect();
```

und auch alle Versuche mit Dispose() sind gescheitert

(die NDde-Dokumentation ist diesbezüglich eben auch sehr dünn)

irgendwer, irgendwelche Ideen und/oder Erfahrungen?


----------



## Jochen Kühner (28 April 2011)

Wird denn der Event "Disconnected" und deine Prozedur "gDdeClient_Disconnected" aufgerufen?


----------



## vierlagig (28 April 2011)

Jochen Kühner schrieb:


> Wird denn der Event "Disconnected" und deine Prozedur "gDdeClient_Disconnected" aufgerufen?



ja, aber wie gesagt bleibt die verbindung offen.


----------



## Jochen Kühner (28 April 2011)

vierlagig schrieb:


> ich sehe per netstat immer noch die offene Verdindung (Status: HERGESTELLT), auch nach mehreren Minuten noch.



Wollt das mal nachstellen, aber wie kann Ich den in Netstat überhaupt die DDE Verbindung sehen?

Ich hab's mit netstat -a -b -n probiert aber mein Prozess taucht nirgends auf!
(Hab den Server und den ClientWin aus dem Samples Ordner benutzt, Verbindung besteht auch!)


----------



## Thomas_v2.1 (28 April 2011)

vierlagig schrieb:


> und auch alle Versuche mit Dispose() sind gescheitert



Hast du schonmal versucht, nach dem Dispose den Garbage Collector manuell mit GC.SuppressFinalize(this) aufzurufen?

Beim Prosim-Objekt war das bei mir die einzige Möglichkeit die Verbindung immer sauber zu trennen, also: IDisposable und Dispose implementieren und darin den GC aufrufen.


----------



## Jochen Kühner (29 April 2011)

Thomas_v2.1 schrieb:


> Hast du schonmal versucht, nach dem Dispose den Garbage Collector manuell mit GC.SuppressFinalize(this) aufzurufen?



Laut Doku ruft doch SuppressFinalize nicht den GC sondern verhindert den Aufruf des Finalizers: http://msdn.microsoft.com/de-de/library/system.gc.suppressfinalize.aspx


----------



## Thomas_v2.1 (29 April 2011)

Jochen Kühner schrieb:


> Laut Doku ruft doch SuppressFinalize nicht den GC sondern verhindert den Aufruf des Finalizers: http://msdn.microsoft.com/de-de/library/system.gc.suppressfinalize.aspx



So gesehen, ja. Ich verstand das im Zusammenhang mit der Implementierung der IDisposable-Schnittstelle, in dem ich quasi mit dem Freigeben meiner eigenen Ressourcen einen eigenen GC baue.

Auf dieser Seite stehen auch noch ein paar Details:
http://openbook.galileocomputing.de...04_008.htm#mj04a34966f39402f97134116af7f94dc6

Ich hatte so ein ähnliches Problem bei dem ProSim COM-Objekte (Plcsim), dort hatte ich ursprünglich die Verbindung zu Plcsim im Destruktor getrennt.
Hier kam es aber manchmal vor, dass der Destruktor nie aufgerufen wurde, oder bei Aufruf des Destruktors das Objekt vom GC
schon aufgeräumt wurde und ungültig war. Eben weil das COM-Objekt sozusagen unmanaged ist, und der GC nicht weiß ob noch Referenzen auf dieses Objekt bestehen.
Dann konnte die Disconnect Methode nicht aufgerufen werden, und Plcsim dachte immer noch es wäre jemand verbunden.
Durch die Implementierung von IDisposable und GC.SuppressFinalize(this) habe ich die Kontrolle über den GC zurückerlangt.


----------



## vierlagig (29 April 2011)

scheint erstmal zu funktionieren... beobachten, weiterfahren
(soll ja (hoffentlich) keine dauereinrichtung sein)


----------



## Thomas_v2.1 (29 April 2011)

vierlagig schrieb:


> scheint erstmal zu funktionieren... beobachten, weiterfahren



Was hast du denn ändern müssen damit es funktioniert? Oder lag das Problem an anderer Stelle...


----------



## vierlagig (29 April 2011)

Thomas_v2.1 schrieb:


> Was hast du denn ändern müssen damit es funktioniert? Oder lag das Problem an anderer Stelle...



ich habe die von dir vorgeschlagenen änderungen eingefügt.


----------



## Jochen Kühner (30 April 2011)

vierlagig schrieb:


> ich habe die von dir vorgeschlagenen änderungen eingefügt.



Welche Änderunge genau?

Nur GC.SuppressFinalize(this) eingefügt?


----------

