Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
GolbalKeyboardHook: Delegat wird vom GC abgeräumt
manunidi
myCSharp.de - Member



Dabei seit:
Beiträge: 229
Herkunft: Niederbayern

Themenstarter:

GolbalKeyboardHook: Delegat wird vom GC abgeräumt

beantworten | zitieren | melden

Hallo,

ich verwende die Klasse "globalKeyboardhook" im Anhang.
Diese funktioniert auch wunderbar, jedoch erhalte ich bei Eingabe von Zeichen in ein Textfeld in einer Form von diesem Programm ab dem 5. Zeichen folgende Fehlermeldung:
Fehler
Für den von der Garbage Collection gesammelten Delegaten vom Typ "outlook2projekt!Utilities.globalKeyboardHook+keyboardHookProc::Invoke" wurde ein Rückruf durchgeführt. Dies kann Anwendungsabstürze, Datenbeschädigung und -verlust zur Folge haben. Beim Übergeben von Delegaten an nicht verwalteten Code müssen die Delegaten von der verwalteten Anwendung beibehalten werden, bis sichergestellt ist, dass sie nie aufgerufen werden.

Hat jemand eine Idee, was das sein könnte?
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von manunidi am .
Attachments
private Nachricht | Beiträge des Benutzers
Floste
myCSharp.de - Member

Avatar #avatar-2376.jpg


Dabei seit:
Beiträge: 1158
Herkunft: Norddeutschland

beantworten | zitieren | melden

Ja dein problem ist diese zeile:

hhook = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hInstance, 0);

Genauer gesagt wird für den parameter hookProc implizit ein delegate erstellt und dieser wird dann vom gc eingesackt...
Erstell den delegaten explizit und speicher ihn in nem member.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Floste am .
Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!
private Nachricht | Beiträge des Benutzers
manunidi
myCSharp.de - Member



Dabei seit:
Beiträge: 229
Herkunft: Niederbayern

Themenstarter:

beantworten | zitieren | melden

Hallo,

ich verstehe vom Prinzip her nicht, warum was ein expliziter und impliziter delegate ist und warum ich ihn in nem member speichern soll. Ich muss dazusagen, das ich diese Klasse im Internet gefunden und verwendet habe, und leider momentan auf dem Schlauch stehe. Es währe nett, wenn du mir genauer beschreibst was ich machen muss...
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von manunidi am .
private Nachricht | Beiträge des Benutzers
mogel
myCSharp.de - Member

Avatar #avatar-3347.jpg


Dabei seit:
Beiträge: 158

beantworten | zitieren | melden

das müsste das hier sein GC.KeepAlive
Du musst dem GC mitteilen, das er den Handle (bzw. Delegate) nicht anschauen darf

GC.ReRegisterForFinalize nicht vergessen
private Nachricht | Beiträge des Benutzers
Floste
myCSharp.de - Member

Avatar #avatar-2376.jpg


Dabei seit:
Beiträge: 1158
Herkunft: Norddeutschland

beantworten | zitieren | melden

GC.KeepAlive kann man getrost übersetzen als: Mach absolut garnichts, aber tu dabei so, alsob du den parameter verwenden würdest => Keinerlei effekt hier

Was ich meine ist:

hhook = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hInstance, 0);
wird implizit umgewandelt in

hhook = SetWindowsHookEx(WH_KEYBOARD_LL, new globalKeyboardHook.keyboardHookProc(this.hookProc), hInstance, 0);
Man beachte das new.
Du musst nichts weiter tun, als den delegaten zu speichern und das genau so lange, bis du den hook wieder mit UnhookWindowsHookEx entfernst:

this.gepeicherterDeleagte=new globalKeyboardHook.keyboardHookProc(this.hookProc);
hhook = SetWindowsHookEx(WH_KEYBOARD_LL, this.gepeicherterDeleagte, hInstance, 0);
Es ist zwar eigendlich unnötig, aber wenn du lustig bist kannst nach der zeile mit UnhookWindowsHookEx noch GC.KeepAlive(this.gepeicherterDeleagte); einfügen.
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Floste am .
Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!
private Nachricht | Beiträge des Benutzers
winSharp93
myCSharp.de - Experte

Avatar #avatar-2918.png


Dabei seit:
Beiträge: 6155
Herkunft: Stuttgart

beantworten | zitieren | melden

Ansonsten bietet sich auch ein GCHandle an, dass du als Klassenmember hältst:
Zitat
[...]
Nach der Reservierung können Sie mit einem GCHandle verhindern, dass das verwaltete Objekt vom Garbage Collector erfasst wird, wenn ein nicht verwalteter Client den einzigen Verweis enthält. Ohne ein solches Handle kann das Objekt vom Garbage Collector erfasst werden, bevor es seine Aufgabe für den nicht verwalteten Client abgeschlossen hat.

Sie können mit dem GCHandle auch ein fixiertes Objekt erstellen, das eine Speicheradresse zurückgibt und verhindert, dass der Garbage Collector das Objekt im Speicher verschiebt.
Dadurch machst du explizit klar, dass der unmanaged Code das Ding braucht - nicht, dass irgendwann mal jemand "bemerkt", dass da ein nicht benötigtes Feld rumliegt...

Zudem stellt ein GCHandle auch sicher, dass der GC das Objekt nicht umkopiert sprich der Pointer ungültig wird.
private Nachricht | Beiträge des Benutzers
Floste
myCSharp.de - Member

Avatar #avatar-2376.jpg


Dabei seit:
Beiträge: 1158
Herkunft: Norddeutschland

beantworten | zitieren | melden

Zitat
Zudem stellt ein GCHandle auch sicher, dass der GC das Objekt nicht umkopiert sprich der Pointer ungültig wird.
Das problem stellt sich garnicht erst, da code (marshalling-stub) und daten (mit dem pointer auf den code) in seperaten heaps liegen. Der stub bleibt also so oder so wo er is...
Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!
private Nachricht | Beiträge des Benutzers
manunidi
myCSharp.de - Member



Dabei seit:
Beiträge: 229
Herkunft: Niederbayern

Themenstarter:

beantworten | zitieren | melden

Danke für die schnelle Hilfe. Ich habs hinbekommen. War komplettes Neuland für mich, aber jetzt versteh ich es :)
private Nachricht | Beiträge des Benutzers
shark
myCSharp.de - Member



Dabei seit:
Beiträge: 1

Lösung

beantworten | zitieren | melden

Zitat von manunidi
Danke für die schnelle Hilfe. Ich habs hinbekommen. War komplettes Neuland für mich, aber jetzt versteh ich es :)

Kannst du deine Lösung bitte Posten? Hab ein ähnliches Problem und komm nicht drauf :/
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Hallo shark,

grundsätzlich ist es natürlich wünschenswert, wenn Hilfesuchende die Lösung, die sie selbst gefunden haben auch mitteilen. Hier steht aber die Lösung ja schon in der ersten Antwort:
Zitat
Erstell den delegaten explizit und speicher ihn in nem member.

Wenn das noch nicht konkret genug ist, hat Floste in seiner zweiten Antwort sehr detailliert geschrieben, was man wie ändern muss.

Beachte vor weiteren Nachfragen bitte vorsorglich [Hinweis] Wie poste ich richtig? Punkt 1.1.1.

herbivore
private Nachricht | Beiträge des Benutzers