Autor Beitrag
MarkusBauer
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 70

Win XP Pro
Delphi 7 PE+Indy
BeitragVerfasst: Di 11.05.10 16:08 
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:

ausblenden volle Höhe 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:
//Benutzte Serverklasse
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: Stringconst 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);
  //warten (hier liegt wohl das Problem)
  //showmessage('warte'); //würde funktionieren
  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; //sollte die Warteschleife eigentlich beenden
end;




//Prozedur um den Server zu initialisieren
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: Di 11.05.10 17:14 
Hi, ich bin mir nicht sicher, aber Du setzt terminate auf false
ausblenden 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);
  //warten (hier liegt wohl das Problem)
  //showmessage('warte'); //würde funktionieren
  while not terminate do
  begin
     sleep(50);
  end;
end;

und prüfst terminate auf false :gruebel:
soll das so sein?

Gruss Alf

_________________
Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
MarkusBauer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 70

Win XP Pro
Delphi 7 PE+Indy
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: Di 11.05.10 17:39 
mh..wo rufst Du denn die procedure TTFTP.IdTrivialFTPServer1TransferComplete(Sender: TObject;....) auf?
Gruss Alf

_________________
Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
MarkusBauer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 70

Win XP Pro
Delphi 7 PE+Indy
BeitragVerfasst: Di 11.05.10 17:49 
ausblenden Delphi-Quelltext
1:
ftp.OnTransferComplete := IdTrivialFTPServer1TransferComplete;					


Die Routine sollte vom TrivialFTPServer aufgerufen werden, wenn er seine Arbeit beendet hat.
ALF
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: 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

_________________
Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
platzwart
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1054
Erhaltene Danke: 78

Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
BeitragVerfasst: Di 11.05.10 18:13 
Probier mal bitte folgendes:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
while not terminate do
  begin
    Application.ProcessMessages;
    sleep(50);
  end;

_________________
Wissenschaft schafft Wissenschaft, denn Wissenschaft ist Wissenschaft, die mit Wissen und Schaffen Wissen schafft. (myself)
MarkusBauer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 70

Win XP Pro
Delphi 7 PE+Indy
BeitragVerfasst: Di 11.05.10 19:06 
Die Prozedur sieht so aus:

ausblenden 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: Stringconst 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
        { On errors, deny access }
        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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: 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))

_________________
Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
MarkusBauer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 70

Win XP Pro
Delphi 7 PE+Indy
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: Di 11.05.10 19:58 
user profile iconMarkusBauer hat folgendes geschrieben Zum zitierten Posting springen:
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

_________________
Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
MarkusBauer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 70

Win XP Pro
Delphi 7 PE+Indy
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: Di 11.05.10 20:54 
user profile iconMarkusBauer hat folgendes geschrieben Zum zitierten Posting springen:
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

_________________
Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
MarkusBauer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 70

Win XP Pro
Delphi 7 PE+Indy
BeitragVerfasst: 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?
ALF
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: Di 11.05.10 21:43 
Hast Du Dir das angeschaut en.wikipedia.org/wik...le_Transfer_Protocol oder de.wikipedia.org/wik...le_Transfer_Protocol
Das meint ich mit Protokoll, damit sollte doch ne vernünftige Rückmeldung zu erfahren sein, die Du mit einbaust um Deine DLL zu entladen Proc zu beenden!

Gruss Alf

_________________
Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!