![]() |
Exception bei Thread-Verwendung
Hallo,
da der IdHTTP mein Programm bei "normaler" Verwendung einfriert, möchte ich dafür einen Thread verwenden. Da ich mich nicht so gut damit auskenne, habe ich die Komponente TIdThreadComponent genommen. Wenn ich jetzt aber mein Programm beende, nachdem der Thread mal gestartet wurde, kommt folgende Exception:
Code:
woran könnte das liegen? Wenn ich die Prozedur, die im Thread aufgerufen wird, normal aufrufe, ist der Fehler verschwunden.
---------------------------
Anwendungsfehler --------------------------- Exception EOSError in Modul UploadTool.exe bei 0000E096. Systemfehler. Code: 1400. Ungültiges Fensterhandle. --------------------------- OK --------------------------- Danke, ManuMF |
Re: Exception bei Thread-Verwendung
Ist TIdAntiFreeze nichts für dich?
|
Re: Exception bei Thread-Verwendung
Schon, wenn es was bringen würde...
Wenn man mehr machen muss, als es bloß aufs Formular zu klatschen, bin ich noch nicht dahintergekommen ;-) Application.ProcessMessages im IdHTTP.onWork läuft zwar, aber das kommt nur so einmal pro Sekunde. |
Re: Exception bei Thread-Verwendung
Du musste es noch irgendwie auf activ stellen, und dem http sagen, er soll es benutzten - wenn ich mich recht erinnere ;)
|
Re: Exception bei Thread-Verwendung
Ersteres war eine meiner ersten Aktionen nach dem Platzieren auf dem formular. Letzteres, also wie ich das mit dem IdHTTP verbinde, habe ich aber nicht rausgefunden. Auch die Indy-Hilfe war nicht hilfreich. :(
|
Re: Exception bei Thread-Verwendung
Vielleicht solltest Du die HTTP-Komponente in einen Thread auslagern...
|
Re: Exception bei Thread-Verwendung
Zitat:
|
Re: Exception bei Thread-Verwendung
Nee, die gesamte Kommunikation. Also, so (ohne die Komponente zu kennen)
Delphi-Quellcode:
Natürlich ist das nur Pseudocode
Procedure TMyThread.Execute;
Var cHttp : THTTPClient; Begin cHtttp := THTTPClient.Create (Nil); Try SetupCommunicationParameter (cHttp); cHttp.SendRequest; cHttp.ReceiveAnswer; Finally cHtt.Free; End End; |
Re: Exception bei Thread-Verwendung
Momentan habe ich die Komponente auf dem Formular sitzen.
Im Thread wird neben der Vorbereitung (laden der Datei in einen Stream, anzeigen des Dateinamens etc.) nur
Delphi-Quellcode:
ausgeführt (mehr braucht die Kompo nicht). Kann es da helfen, das Create & Co. mit in den Thread zu nehmen?
IdHTTP.Post(Stream, URL);
|
Re: Exception bei Thread-Verwendung
Hi,
Du solltest die Komponente nach Möglichkeit dynamisch innerhalb des Threads erstellen. Oder du realisierst sämtliche Zugriffe auf die Komponente per Syncronize. Ersteres ist IMO zu bevorzugen. |
Re: Exception bei Thread-Verwendung
Jetzt wollte ich das gerade umsetzen, da bin ich an ein weiteres Problem gestoßen: Ich muss auch aus anderen Prozeduren auf den IdHTTP zugreifen, etwa um ihn per Buttonclick zu stoppen. Das geht also leider nicht :(
|
Re: Exception bei Thread-Verwendung
Natürlich geht das. Dazu musst du nur den Zugriff (threadsicher!) auf die HTTP-Komponente über den Thread implementieren.
|
Re: Exception bei Thread-Verwendung
Berühmte Frage ;-) : Wie?
|
Re: Exception bei Thread-Verwendung
Hi,
Schon mal was von ![]() Oder du benutzt einen Flag und lässt den Thread die Arbeit tun. |
Re: Exception bei Thread-Verwendung
bisher noch nicht, hab grad mal geschaut... uff, das ist ein sehr umfangreiches Thema.
Das mit CriticalSection hab ich nicht wirklich verstanden. Dafür habe ich stattdessen die Komponente (IdThreadComponent) entfernt und den Thread selbst erzeugt. Wenn ich, wie hier gelesen, das ganze synchronisiert mache, gestaltet sich der Ablauf so, als ob es gar keinen Thread gäbe (Programm reagiert nicht oder selten). Wenn ich den eigenen Thread unsynchronisiert laufen lasse, reagiert das Programm problemlos: Die Progressbars erden aktualisiert, Klicks angenommen. Nur am Ende wieder die Exception mit dem Handle :( Das Problem bei der Sache ist, dass die Progressbars etc. im onWork des IdHTTP aktualisiert werden, ich kann also nicht einfach die ganze Komponente in denThread verschieben. |
Re: Exception bei Thread-Verwendung
Versuch mal die Komponente Dynamisch im Thread zu erzeugen, zunächst mal ohne Progress usw. wenn das soweit geht kannst dun nach und nach die Visualisierung einbauen.
Was das hängen betrifft, wenn du z.B: IDHttp.Get syncronisierst kannst du dir den Thread auch gleich schenken. Zeig mal ein bischen relevanten Code |
Re: Exception bei Thread-Verwendung
Hmm also wenn ich die Progressbars ausbaue, dann können sie nicht mehr stocken, und das Problem ist natürlich gelöst ;)
Wie oben geschrieben, die einzige Zeile Code, sie aber eben das ganze Prog aufhält, ist IdHTTP.Post. Die Aktualisierung mache ich im onWork, deshalb wäre die dynamische Erzeugung eigentlich nutzlos, da der Zugriff auf die VCL ja bleibt. Übrigens wäre auch eine Aktualisierung per Timer nutzlos, da das Timer-Event nicht wie eingestellt kommt, sondern nur, wenn onWork ausgeführt wird und darin ProcessMessages steht. Wie kann ich denn Post synchronisieren? Bzw. durch das Synchronisieren hängt alles erst ja. |
Re: Exception bei Thread-Verwendung
Hallo,
synchronisiere nicht post. verarbeite im thread das OnWork-Event und Synchronisiere dann ein Event, das du nach außen reichst. |
Re: Exception bei Thread-Verwendung
Zitat:
|
Re: Exception bei Thread-Verwendung
Ich mach mal ein Pseudocode Beispiel.
Delphi-Quellcode:
Ich hoffe jetzt wird es klar was wir meine (ich hoffe DGL-Luke hat das auch so ähnlich gemeint)
procedure MyOnWorkEvent(...);
begin ... Syncronize(MyGUIUpdate); ... end; procedure MyGUIUpdate; begin ... Progressbar.Position := MyProgress; ... end; |
Re: Exception bei Thread-Verwendung
Jetzt hab ichs verstanden :-D
OK, dann probiere ich es mal so. Dann muss ich nur noch ein wenig umschreiben, da vor dem Post noch die Bars auf 0 gestellt werden etc., das muss dann wohl auch noch in eine synchronisierte Prozedur... oder kann ich quasi im Thread einen Bereich als synchronisiert bestimmen? Ach so, und kann ich im Thread auf globale Variablen zugreifen? [Edit] Stopp, das ganze funktioniert nicht. Ich muss per ButtonClick das IdHTTP stoppen können (.disconnect). Das geht aber natürlich nicht, wenn ich es dynamisch im Thread erstelle. :wall: [/edit] |
Re: Exception bei Thread-Verwendung
Zitat:
|
Re: Exception bei Thread-Verwendung
Also z.B. MyThread.StopUpload und das im ButtonClick aufrufen? :gruebel:
|
Re: Exception bei Thread-Verwendung
Jupp. Probier's. In der StoppHttp-Methode solltest Du mit etwas Glück nur Disconnect aufrufen.
|
Re: Exception bei Thread-Verwendung
Ja, genau so hab ich es vorher gemacht.
Ich habe das Ganze nun umgesetzt. Es besteht hier aber weiter das Problem, dass das Programm nur regiaert, wenn ich im (synchronisierten) work-Update-Event ProccessMessages ausführe, sonst gar nicht. Ich habe das so wie oben vorgeschlagen angelegt, also im onWork wird eine Prozedur synchronisiert aufgerufen, die die Progresbars setzt. Liegt es vielleicht daran, dass ich das Uploaden als Funktion anlege, da ich wissen muss, ob er fehlgeschlagen ist? Hier ein bisschen Code:
Delphi-Quellcode:
ansonsten wenigstens keine AVs oder sonstige Probleme :-D
function TUploadThread.DoUpload(URL: String; Stream: TStream; RCT: String; out AW: String): Boolean;
begin IdHTTPC.Request.ContentType := RCT; result := true; try AW := IdHTTPC.Post(URL, Stream); except result := false; end; end; // Aufruf in einer "normalen" Prozedur außerhalb des Threads if (UploadThread.DoUpload(DURL, Stream, RCT, AW)) then LogFeld.Items.Add(' Erfolgreich.') else [Fehlerbehandlung] |
Re: Exception bei Thread-Verwendung
Du rufst doch gar keinen Thread auf!
Die Arbeit des Threads wird durch seine Execute-Methode definiert. Dort, und nur dort arbeitet der Thread im Hintergrund. |
Re: Exception bei Thread-Verwendung
Ach so. Dann bringt aber der Vorschlag von C.Schoch bzw. DGL-luke nichts, oder? :wiejetzt:
|
Re: Exception bei Thread-Verwendung
Liste der Anhänge anzeigen (Anzahl: 1)
Hi,
Klar bringen unsere Vorschläge etwas, du solltest den Thread nur auch mal anschmeißen und nicht eine im Thread deklarierte Funktion aus dem Haupthread aufrufen. Ich hab mal auf die schnelle ne Demo zusammengebaut allerdings einen Download (Upload ist aber gleich zu implementieren), Fehlerbehandlung usw sind noch nachzurüsten. Um die Meldung "Fehler" zu provozieren einfach das Programm mir der Firewall blockieren. Edit: Vieleicht solltest du dich erstmal mit den Grundlagen von Threads vertraut machen z.B. mit Luckies Thread ![]() |
Re: Exception bei Thread-Verwendung
(Der Fehler liegt wohl an einem Verständnisproblem. Soweit wie möglich bin ich das Tutorial nämlich schon durchgegangen.)
Aber ich pendele hier ständig von einem Problem zum nächsten: Dein Beispiel ist super (danke dafür!), aber es berücksichtigt wieder nicht, dass ich das IdHTTP per Buttonclick stoppen können muss. Außerdem geschieht der Upload in einer Schleife. Was muss ich da tun? Den Thread jedes mal wieder neu erzeugen und starten? |
Re: Exception bei Thread-Verwendung
Hi,
Ich will dir ja nicht die Lösung auf dem Silbertablett präsentieren, du willst doch auch was lernen oder? Das mit dem Abbruch ist einfach, hierfür besitzt ein Thread Objekt die Eigenschaft Terminated. Den Thread würde ich nicht jedes mal neu starten. Ein Ansatz wäre dem Thread eine Liste mit Urls zu übergeben, die er dann abarbeitet. |
Re: Exception bei Thread-Verwendung
Sicher will ich was lernen, sonst müsste ich ja immer wieder hier zu Threads nachfragen ;-)
Ich dachte auch schon an Terminated, aber wie mache ich das dem IdHTTP klar? OK, ich könnte es mal im onWork probieren, das wird ja ständig aufgerufen. Das mit der Liste wäre sehr einfach, wenn ich keine GUI hätte. Sprich: In der Schleife, in der hochgeladen wird, passiert einiges. Ich schreibe da eine Art Log in ein Memo, zeige an, welche Datei er hochlädt, wie groß sie ist etc. Das heißt, ich müsste eine Unzahl an Variablen anlegen, in die das gespeichert wird. Nicht nur das, ich muss auch auf eine Listbox und diverse andere Controls zugreifen, die das Verhalten steuern. Das Ganze erweist sich also als äußerst kompliziert :-( Naja, ich probiers mal. |
Re: Exception bei Thread-Verwendung
Auch ich hätte gerne ein Synchronize das eine Prozedure mit Variablen aufrufen kann.
Da das nicht geht wirst du wohl um die Variablen nicht herumkommen. Wenns noch Fragen gibt einfach Posten. |
Re: Exception bei Thread-Verwendung
Ja, eine wäre da noch (den Rest hab ich geschafft) :-D
Das Problem tritt in folgender Situation auf: Ich starte den Upload mitsamt Thread normal. Mittendrin breche ich ab, rufe also Thread.Terminate auf. Im onWork erkennt er das und disconnected das IdHTTP. Meine Fehlermeldung wird angezeigt. So weit, so gut. Nun möchte ich aber wieder den Upload starten. Was muss ich dazu aufrufen? So bricht der Thread immer ab, da ja Terminated auf true steht. Hat sich erledigt, ich erstelle den Thread einfach jedes mal, wenn ich einen Upload beginne. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:55 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz