Laden...

[gelöst] Fehler bei der Drag&Drop-Registrierung

Erstellt von JasonDelife vor 13 Jahren Letzter Beitrag vor 13 Jahren 7.159 Views
J
JasonDelife Themenstarter:in
237 Beiträge seit 2008
vor 13 Jahren
[gelöst] Fehler bei der Drag&Drop-Registrierung

Hallo zusammen.
Ich habe eine WinForms-Applikation geschrieben, bei der ein Control Drag&Drop nutzt (AllowDrop = true).
Das Problem ist, dass ab und zu (ohne erkennbares Muster) ein Fehler auftaucht, in Form des WinForms-Exceptiondialogs:

System.InvalidOperationException: Fehler bei der DragDrop-Registrierung ---> System.Threading.ThreadStateException: Für den aktuellen Thread muss der STA-Modus (Single Thread Apartment) festgelegt werden, bevor OLE-Aufrufe ausgeführt werden können. Stellen Sie sicher, dass die Hauptfunktion mit STAThreadAttribute gekennzeichnet ist.
bei System.Windows.Forms.Control.SetAcceptDrops(Boolean accept)
--- Ende der internen Ausnahmestapelüberwachung ---
bei System.Windows.Forms.Control.SetAcceptDrops(Boolean accept)
bei System.Windows.Forms.Control.OnHandleCreated(EventArgs e)
bei System.Windows.Forms.Control.WmCreate(Message& m)
bei System.Windows.Forms.Control.WndProc(Message& m)
bei System.Windows.Forms.ScrollableControl.WndProc(Message& m)
bei System.Windows.Forms.ContainerControl.WndProc(Message& m)
bei System.Windows.Forms.UserControl.WndProc(Message& m)
bei System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
bei System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
bei System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

Klicke ich in der Box auf weiter, so greift sofort danach mein Exceptionhandler und sagt mir dass ich ein Control aus einem Thread nicht einem Control aus einem anderen Thread hinzufügen kann.
Mit dem Stack des ersten Fehlers kann ich leider wenig anfangen und ich habe schon mehrmals geprüft, dass das Control wirklich im gleichen Thread erstellt wird (was in meinen Tests der Fall war, aber offensichtlich nicht immer). Meine Main-Methode ist mit STAThread gekennzeichnet.
In letzter Zeit tritt der Fehler auch nicht mehr bei meinem Rechner auf, allerdings auf dem eines Freundes sehr häufig.
Komisch ist ebenfalls, dass ich den Fehler nur dann beobachten konnte, wenn mein Control ein animiertes GIF darstellt (per GDI+ und ImageAnimator), allerdings prüfe ich im OnNextFrame auf InvokeRequired und handle entsprechend.
Ich habe auch ein wenig das VB-Framework im Verdacht, das benutze ich nämlich für die Darstellung eines Splash-Screens. Ich kann nur bei mir nicht testen, da der Fehler wie gesagt irgendwie nicht mehr auftritt und mein Freund hat leider wenig Zeit. Ich versuche mal morgen bei ihm eine Version ohne VB-Splash zu testen.

Vielleicht habt ihr ja noch Ideen.
PS: Falls Code benötigt wird, stehe ich natürlich zur Verfügung. Ich wollte nur jetzt nicht das halbe Programm posten, da ich ja nicht weiß, welche Teile interessant sein könnten.

Grüße, JasonDelife.

Beim Programmieren löst man die Probleme, die man nicht hätte, programmierte man nicht.

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo JasonDelife,

im Grunde hast du schon die wichtigsten Prinzipien korrekt beschrieben. Du musst dafür sorgen, dass alle Controls aus dem mit STAThread gekennzeichneten Main-Thread erzeugt werden. Auch alle Zugriffe auf die Controls müssen aus diesem Thread erfolgen. Dazu musst du nötigenfalls Control.Invoke verwenden, wenn der Anstoß aus einem Thread kommt. Wie man an ImageAnimator.OnNextFrame sehen kann, kann der eigene Code durchaus mal in einem extra Thread laufen, ohne dass man selbst einen extra Thread erstellt hat. Und natürlich ist das auch bei dem VB-Splash nicht ausgeschlossen.

Auch wenn du schon mehrfach geprüft hast, dass alles notwendige im Main-Thread läuft, so muss es doch etwas geben, was du übersehen hast. Die Meldung, die du bekommst, lässt daran ja keinen Zweifel. Die Stelle kann natürlich überall und nirgends liegen. Insofern gebe ich dir recht, dass es nicht sinnvoll ist, Code zu posten. Ein Ausschnitt reicht nicht und das Ganze wäre sicher zu umfangreich.

Du kannst aber das tun, was ich in Es werden nicht alle Tabstopps angesprungen beschrieben habe, um den Fehler einzugrenzen.

herbivore

5.742 Beiträge seit 2007
vor 13 Jahren

Hallo JasonDelife,

logge mal ein paar ThreadIds mit - vielleicht tritt ja doch zu Tage, dass irgendwo ein anderer Thread am Werke ist.

J
JasonDelife Themenstarter:in
237 Beiträge seit 2008
vor 13 Jahren

Ich habe nun auf dem PC meines Freundes mal eine Version ohne VB-Splash getestet.
Resultat:
10x öffnen -> 0x Fehler
2x alte Version mit Splash -> beim zweiten mal schon der Fehler
Ich habe auch mal den Code des VB-Frameworks im Reflector angeschaut und herausgefunden, dass der Splash-Code DoEvents() nutzt.
Aufgrund des Test und da ich DoEvents() so ziemlich alles zutraue gehe ich davon aus, dass der VB-Splash das Problem ist und werde dann mal nach Alternativen suchen.
Sollte der Fehler trotzdem mal wieder auftauchen oder ich etwas mehr Zeit haben, dann werde ich eure Tipps befolgen.
EDIT: Habe mal dem Titel ein "GELÖST" vorangestellt und hoffe sehr, dass das auch so bleiben wird 😉 .

Vielen Dank für eure Hilfe!
Grüße, JasonDelife.

Beim Programmieren löst man die Probleme, die man nicht hätte, programmierte man nicht.