Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Sleep ohne Freeze
MarkusBauer - Di 11.05.10 16:08
Titel: Sleep ohne Freeze
Hallo
ich habe eine DLL geschrieben, die über einen TrivialFTP-Server Daten empfangen bzw. versenden und sich anschließend beenden soll. Das Ganze soll ohne ein Formular stattfinden. Allerdings muss die Prozedur dazu auf das Ende der Übertragung abwarten. Hier der Code:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66:
| type TTFTP = class ftp: TIdTrivialFTPServer; procedure FTPInit(port: Integer); procedure IdTrivialFTPServer1TransferComplete(Sender: TObject; const Success: Boolean; const PeerInfo: TPeerInfo; AStream: TStream; const WriteOperation: Boolean); procedure IdTrivialFTPServer1ReadFile(Sender: TObject; var FileName: String; const PeerInfo: TPeerInfo; var GrantAccess: Boolean; var AStream: TStream; var FreeStreamOnComplete: Boolean); procedure IdTrivialFTPServer1WriteFile(Sender: TObject; var FileName: String; const PeerInfo: TPeerInfo; var GrantAccess: Boolean; var AStream: TStream; var FreeStreamOnComplete: Boolean); end;
var server: TTFTP; terminate: Boolean;
procedure Run; stdcall; begin terminate := false; server := TTFTP.Create; server.FTPInit(port); while not terminate do begin sleep(50); end; end;
procedure TTFTP.IdTrivialFTPServer1TransferComplete(Sender: TObject; const Success: Boolean; const PeerInfo: TPeerInfo; AStream: TStream; const WriteOperation: Boolean); begin try If Assigned(AStream) then FreeAndNil(AStream); except end; showmessage('done'); terminate := true; end;
procedure TTFTP.FTPInit(port: Integer); begin ftp := tIdTrivialFTPServer.create( nil ) ; ftp.DefaultPort := port; ftp.ThreadedEvent := true; ftp.OnReadFile := IdTrivialFTPServer1ReadFile; ftp.OnTransferComplete := IdTrivialFTPServer1TransferComplete; ftp.Active := true; end;
exports Run; |
Die Datei wird zwar komplett übertragen, allerdings wird die TransferComplete-Routine nicht aufgerufen, die Anwendung läuft auch nach der Übertragung weiter. Dies liegt wohl an der Warteschleife (while not terminate do...), wenn ich statt dieser die auskommentierte showmessage-Funktion benutze funktioniert alles.
Gibt es eine Möglichkeit auf das Ende der Aktion zu warten, ohne das komplette Programm lahmzulegen?
Danke
Markus
ALF - Di 11.05.10 17:14
Hi, ich bin mir nicht sicher, aber Du setzt terminate auf false
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| procedure Run; stdcall; begin terminate := false; server := TTFTP.Create; server.FTPInit(port); while not terminate do begin sleep(50); end; end; |
und prüfst terminate auf false :gruebel:
soll das so sein?
Gruss Alf
MarkusBauer - Di 11.05.10 17:18
ja das sollte so sein. terminate gibt an, ob die Anwendung beendet werden soll.
Die Schleife soll so lange laufen, wie das Programm noch nicht beendet werden soll. In der TransferComplete-Routine sollte terminate auf true gesetzt werden, dann sollte die Schleife beenden. So wars zumindest gedacht ...
ALF - Di 11.05.10 17:39
mh..wo rufst Du denn die procedure TTFTP.IdTrivialFTPServer1TransferComplete(Sender: TObject;....) auf?
Gruss Alf
MarkusBauer - Di 11.05.10 17:49
Delphi-Quelltext
1:
| ftp.OnTransferComplete := IdTrivialFTPServer1TransferComplete; |
Die Routine sollte vom TrivialFTPServer aufgerufen werden, wenn er seine Arbeit beendet hat.
ALF - Di 11.05.10 17:59
sorry hab es übersehen mhh.., bei den langen Procedure namen brauch man ne weile :wink:
Wie sieht den die Procedure IdTrivialFTPServer1ReadFile aus?
Wenn Du sagst, das es gar nicht bis zum Aufruf von IdTrivialFTPServer1TransferComplete kommt!
heist also, die Meldung aus der Proc -showmessage('done')- kommt also auch nicht!?
Gruss Alf
platzwart - Di 11.05.10 18:13
Probier mal bitte folgendes:
Delphi-Quelltext
1: 2: 3: 4: 5:
| while not terminate do begin Application.ProcessMessages; sleep(50); end; |
MarkusBauer - Di 11.05.10 19:06
Die Prozedur sieht so aus:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| procedure TTFTP.IdTrivialFTPServer1ReadFile(Sender: TObject; var FileName: String; const PeerInfo: TPeerInfo; var GrantAccess: Boolean; var AStream: TStream; var FreeStreamOnComplete: Boolean); var FS : TFileStream; begin FreeStreamOnComplete := True; try if uppercase(Filename) = uppercase(extractfilename(f)) then begin FS := TFileStream.Create(f, fmOpenRead or fmShareDenyWrite); AStream := FS; GrantAccess := True; end else begin GrantAccess := False; end; except GrantAccess := False; If Assigned(FS) then FreeAndNil( FS ); end; end; |
Also showmessage('done') kommt nicht, aber die Datei wird komplett übertragen. Ich vermute dass das Transfer-Complete-Event nicht abgearbeitet wird da die Warteschleife noch alle Ressourcen belegt.
Application.ProcessMessages bringt keinen Unterschied, auch nicht wenn ich vor Application.Initialize; und Application.Run; ausführe.
Hidden - Di 11.05.10 19:15
((und jetzt nimm' noch das sleep raus. Busy waiting sollte ja nicht besser sein, als die Ganze Zeit auf Fensterbefehle zu reagieren))
MarkusBauer - Di 11.05.10 19:30
Ohne Sleep bringt keine Änderungen, außer dass die CPU voll ausgelastet wird. Application.ProcessMessages scheint nichts zu bringen, da die Anwendung kein Formular hat (Konsolenanwendung ohne {APPTYPE: CONSOLE}).
ALF - Di 11.05.10 19:58
MarkusBauer hat folgendes geschrieben : |
Ich vermute dass das Transfer-Complete-Event nicht abgearbeitet wird... |
Das ist ja schon bekannt! Aber woher erhälts Du die info, das die Datei übertragen wurde?
nur so macht es sinn die Proc IdTrivialFTPServer1TransferComplete überhaupt aufzurufen!
So wie es aussieht, ohne slepp, nur mit showmessage-Funktion funct es doch, laut Deiner ertsen Aussage!
Gruss Alf
MarkusBauer - Di 11.05.10 20:23
Die Info erhalte ich dadurch, dass die Datei nach dem Vorgang vollständig und korrekt im Zielverzeichnis liegt. Ja, wenn ich statt der Sleep-Routine die Showmessage-Box nutze funktionierts, allerdings kann ich dem Nutzer schlecht eine MessageBox mit "bitte drücken sie hier, wenn alles abgeschlossen ist" präsentieren.
ALF - Di 11.05.10 20:54
MarkusBauer hat folgendes geschrieben : |
Die Info erhalte ich dadurch, dass die Datei nach dem Vorgang vollständig und korrekt im Zielverzeichnis liegt. |
Aber doch nicht als Rückgabe für Deine Procedure!
Wie willst Du sonst die kontrolle haben (Protokoll)?
Warum lässt Du die Message nicht einfach weg!
Legst ne logfile zur kontrolle an. mhh.. solltest Du vielleicht mit einbauen falls irgenwo was schief geht!
Gruss Alf
MarkusBauer - Di 11.05.10 21:34
Die Prozedur wird ja auch nicht von mir, sondern von der TTrivialFTP-Komponente aufgerufen. Die Message brauch ich nur, damit sich das Programm beendet, nachdem die Datei übertragen wurde, ob das Ganze erfolgreich war oder nicht ist eigentlich unwichtig. Gibts vllt. ne andere Art das Programm nach der Übertragung zu beenden?
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!