Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Thread stürzt aber, aber nur unter Win 2003, nicht unter XP (https://www.delphipraxis.net/74634-thread-stuerzt-aber-aber-nur-unter-win-2003-nicht-unter-xp.html)

Florian_Meyer 6. Aug 2006 21:05


Thread stürzt aber, aber nur unter Win 2003, nicht unter XP
 
Hallo,

ich habe ein Programm geschrieben, das Dateien ins Internet uploaden soll. So weit so gut, klappt unter Windows XP auch hervorragend: In einem extra Thread wird eine Datenbank abgefragt, mit dem zugangsdaten und der datei usw. und dann wird die Datei hochgeladen. Wie gesagt, unter Windows XP: kein Problem.
Allerdings unter Windows Server 2003: Der Thread läuft seinen Programmcode einmal durch, lädt die Datei hoch, aber danach stürzt der Thread irgendwie ab. Im Task-Manager wird dann ab diesem Moment nur noch ein Thread weniger angezeigt.

Hat jemand eine Idee, woran das liegen kann?

Bin für jede Hilfe dankbar!

MfG
Florian Meyer

RavenIV 7. Aug 2006 07:31

Re: Thread stürzt aber, aber nur unter Win 2003, nicht unter
 
Nutzt Du Funktionen der WinApi?
Evtl hat sich die Api bei Win2003Server geändert?

Auf jeden Fall solltest Du an vielen kritischen Punkten MsgBoxen einbauen, damit Du "debuggen" kannst. Oder kannst Du auf dem Server das Delphi installieren zum debuggen?

Bernhard Geyer 7. Aug 2006 07:42

Re: Thread stürzt aber, aber nur unter Win 2003, nicht unter
 
Bei D2006 sollte es nicht nötig sein Delphi zu installieren. Hier gibt es wieder den Remote-Debugger womit es reicht nur den zu installieren und sich dann mit der laufenden Instanz zu verbinden.

Aber frag mich nicht welche Schalter du unter D2006 einstellen/drücken mußt. Hab Remote-Debugging nur mal bei D7 ausprobiert.

Florian_Meyer 7. Aug 2006 15:44

Re: Thread stürzt aber, aber nur unter Win 2003, nicht unter
 
Hallo,

ja, das könnte sein, dass sich bei der API was geändert hat, aber was mich allerdings wundert, dass der Code ja genau 1-Mal durchlaufen wird...

Also wie das mit dem Remote-Debigging geht weiß ich leider auch nicht...ich werde es nochmal mit dem MsgBoxen probieren...

MfG
Florian Meyer

Peter Wolf 8. Aug 2006 08:04

Re: Thread stürzt aber, aber nur unter Win 2003, nicht unter
 
Hallo Florian,

ich hatte ein ähnliches Problem sowohl unter Windows 2000 Server, als auch Windows 2003 Server.
Ich denke es waren irgendwelche Sicherheitseinstellungen, denn nachdem mein Kollege den Server "defaultmäßig" neu aufgesetzt hat, gab es keine Probleme mehr.
Vielleicht hilft Dir diese Aussage weiter?

Grüße
Peter

Florian_Meyer 8. Aug 2006 08:34

Re: Thread stürzt aber, aber nur unter Win 2003, nicht unter
 
Hallo Peter,

leider nützt mir diese Aussage auch nicht viel weiter, weil wir den Server gerade letzte Woche neu aufgesetzt haben. Und wirklich viele Programme sind auch nicht installiert.



Aber wie ich grad festgestellt hab, müsste ich den Titel hier nochmal ändern, weil ich habe soeben gemerkt, dass der Thread nicht nur unter Windows Server 2003, sondern auch unter Win XP abschmiert.
Zwar ist es so, dass der Thread aufm server nur einmal durchlaufen wird und danach abstürzt, aber beim XP-Rechner ist es genauso, bis auf, dass es dort erst nach ein paar Minuten so ist.

Ich bin echt am Verzweifeln...
Scheinbar stürzt dabei ab, wenn ich etwas mit einer Absolute DB machen will.

Achtung*g*: Hier kommt etwas sehr langer Code. Dies ist der gesamte Thread.
ich makiere mal die Stelle, an welcher der Thread abstürzt.

Delphi-Quellcode:
unit uThread2;

interface

uses Classes,Windows, SysUtils, Variants;

type
  TUpdateLocation = (ulDatabaseActive, ulDatabaseDeActive, ulTimestamp, ulMemo, ulTable3Active, ulTable3First, ulTable3DeActivate, UploadSchlangeTableDelete, UploadSchlangeTableNext);
  TUpdateLocations = set of TUpdateLocation;

  TThread2 = class(TThread)
  private
    UpdateString: string;
    UpdateLocations: TUpdateLocations;
    procedure MySynchronizeEx;
    procedure MySynchronize(astring: string; AUpdateLocation: TUpdateLocations);
  protected
    procedure Execute; override;
 end;

implementation

uses uMain, IdFTPCommon;

const
UnixStartDate: TDateTime = 25569.0;

function DateTimeToUnix(ConvDate: TDateTime): Longint;
begin
  Result := Round((ConvDate - UnixStartDate) * 86400);
end;

function UnixToDateTime(USec: Longint): TDateTime;
begin
  Result := (Usec / 86400) + UnixStartDate;
end;

procedure TThread2.Execute;
var
  iStart: Cardinal;
  iEnde: Cardinal;
  uploadid, port: integer;
  server,user,password,qpath,spath: string;
begin
  repeat
    iStart := getTickCount;
    try
      if not MainForm.ABSDatabase1.Connected then
      begin
        MySynchronize('',[ulDatabaseActive]);
      end;
      if not MainForm.UploadSchlangeTable2.Active then
      begin
        MySynchronize('',[ulTable3Active,ulTable3First]);
      end;
      while not MainForm.UploadSchlangeTable2.Eof do
      begin
        uploadid := MainForm.UploadSchlangeTable2.FieldByName('iID').AsInteger;
        server := MainForm.UploadSchlangeTable2.Lookup('iID',uploadid,'sServer');
        port := MainForm.UploadSchlangeTable2.Lookup('iID',uploadid,'iPort');
        user := MainForm.UploadSchlangeTable2.Lookup('iID',uploadid,'sUser');
        password := MainForm.UploadSchlangeTable2.Lookup('iID',uploadid,'sPassword');
        spath := MainForm.UploadSchlangeTable2.Lookup('iID',uploadid,'sSpath');
        qpath := MainForm.UploadSchlangeTable2.Lookup('iID',uploadid,'sQPath');
        // Beginne Upload-Prozess
        MySynchronize('--------------- starting upload '+inttostr(uploadid)+' on '+DateToStr (Date) + ' - ' + TimeToStr (Time)+' -----',[ulMemo]);
        MainForm.UploadFTP.Host := server;
        MainForm.UploadFTP.Port := port;
        MainForm.UploadFTP.Username := user;
        MainForm.UploadFTP.Password := password;
        MySynchronize('===== connecting to '+server+' =====',[ulMemo]);
        try
          MainForm.UploadFTP.Connect;
          MySynchronize('===== connection established =====',[ulMemo]);
        except
          MySynchronize('===== connection failed =====',[ulMemo]);
        end;
        if MainForm.UploadFTP.Connected then
        begin
          MainForm.UploadFTP.ChangeDir(spath);
          MySynchronize('===== uploading =====',[ulMemo]);
          try
            MainForm.UploadFTP.Put(qpath,ExtractFileName(qpath));
            MySynchronize('===== upload successful =====',[ulMemo]);
          except
            MySynchronize('===== upload failed =====',[ulMemo]);
          end;
          MainForm.UploadFTP.Disconnect;
          MySynchronize('===== connection closed =====',[ulMemo]);
        end;
        MainForm.UploadSchlangeTable2.Delete;
manchmal stürzt er hier ab
Delphi-Quellcode:
        MainForm.UploadSchlangeTable2.Next;
manchmal auch hier
Delphi-Quellcode:
      end;
    finally
      if MainForm.ABSDatabase1.Connected then
      begin
        MySynchronize('',[ulDatabaseDeActive]);
      end;
und manchmal auch hier
Delphi-Quellcode:
    end;
    iEnde := getTickCount;
    sleep(10000-(iEnde-iStart));
  until (terminated);
end;

procedure TThread2.MySynchronize(Astring: string;
  AUpdateLocation: TUpdateLocations);
begin
  UpdateLocations := AUpdateLocation;
  UpdateString := AString;
  Synchronize(MySynchronizeEx);
end;

procedure TThread2.MySynchronizeEx;
var
  AUpdateLocation: TUpdateLocation;
begin
  for AUpdateLocation in UpdateLocations do
  begin
    case AUpdateLocation of
      ulDatabaseActive: MainForm.ABSDatabase1.Connected := true;
      ulDatabaseDeActive: MainForm.ABSDatabase1.Connected := false;
      ulMemo: MainForm.mNetwork.Lines.Add(UpdateSTring);
      ulTable3Active: MainForm.UploadSchlangeTable2.Active := true;
      ulTable3First: MainForm.UploadSchlangeTable2.First;
      ulTimestamp: MainForm.eUnixTime.Text := Updatestring;
      ulTable3DeActivate: MainForm.UploadSchlangeTable2.Active := false;
      UploadSchlangeTableDelete: MainForm.UploadSchlangeTable2.Delete;
      UploadSchlangeTableNext: MainForm.UploadSchlangeTable2.Next;
    end;
  end;
end;

end.

xaromz 8. Aug 2006 08:47

Re: Thread stürzt aber, aber nur unter Win 2003, nicht unter
 
Hallo,

Du greifst in Deinem Thread an allen Ecken und Enden unsynchronisiert auf VCL-Objekte des Hauptthreads zu. Dass es da irgendwann knallt ist eigentlich keine Frage des Ob? sondern eine Frage des Wann?
Wenn Du nicht 100% sicher bist, dass ein Objekt threadsafe ist (die komplette VCL ist es z. B. nicht), dann musst Du immer Synchronize benutzen.
Die Alternative wären Criticalsections, um den Code zu schützen, wobei das mehr Aufwand bedeutet, fehlerträchtiger ist und oft (Fremdkomponenten) nicht machbar ist. Ist es aber machbar, ist oft eine bessere Laufzeit als mit Synchronize zu erwarten.

Gruß
xaromz

Florian_Meyer 8. Aug 2006 10:04

Re: Thread stürzt aber, aber nur unter Win 2003, nicht unter
 
Hallo,

danke erstma. Muss ich denn auch synchronisiert auf den Hauptthread zugreifen, wenn ich nur etwas von ihm lesen möchte, oder nur beim schreiben auf den Hauptthread?

Naja, ich kenne mich allegemein mit den Threads noch nicht besonders gut aus...ich werd mir das mit den Critical Sections nochmal durch den Kopf gehen lassen...

Grüße
Florian Meyer

xaromz 8. Aug 2006 10:23

Re: Thread stürzt aber, aber nur unter Win 2003, nicht unter
 
Hallo,
Zitat:

Zitat von Florian_Meyer
Muss ich denn auch synchronisiert auf den Hauptthread zugreifen, wenn ich nur etwas von ihm lesen möchte, oder nur beim schreiben auf den Hauptthread?

Auch beim Lesen kann es passieren, dass Du einen Wert einliest, der sich gerade verändert. Dadurch ist der gelesene Wert undefiniert. Solange Du hier keine Speicheradressen liest (Pointer, Objekte...), kann nicht mehr passieren, als dass Du mit falschen Daten rechnest. Holst Du Dir aber Pointer, dann gibt's beim nächsten Zugriff eine schöne AV.

Gruß
xaromz

Muetze1 18. Sep 2006 11:21

Re: Thread stürzt aber, aber nur unter Win 2003, nicht unter
 
Auch wenn es alt ist: Die DB ISAM Treiber die von Borland mitgeliefert werden verursachen bei eingeschalteter DEP (data execution prevention) eine AV. Dieses ist dann aber schon beim Starten der IDE durch AV's beim Package Load zu bemerken. Aufgetreten u.a. unter Delphi 5. Abhilfe. DEP für die Delphi IDE abschalten bzw. für dein Programm, wenn dieses mit genau diesen DB Treibern arbeitet.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:42 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