Autor |
Beitrag |
Bronstein
      
Beiträge: 578
Erhaltene Danke: 1
WIN XP
Delphi 6 / Delphi 2006 / Delphi XE
|
Verfasst: Sa 10.11.07 12:31
Hallo,
ich möchte mit Hilfe eines Threads Daten aus Textdateien in eine Datenbank schreiben. Das schreiben in die Datenbank funktioniert auch, mein Thread erreicht aber nie das Ende meiner Schleife in der Excecute Funktion. Zu dem Code wo ich das Kommentar "//prüfen ob Subnetz übertragung aktiviert" gelangt er nie?
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: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150:
| unit traceKonverter;
interface
uses Classes, SysUtils, ADODB, ActiveX, DateUtils, QGraphics;
type Trace = class(TThread) private protected procedure Execute; override; end;
implementation
uses main, funktionen, settings;
function Datenuebertragung(Pfad: ShortString; LastTime: TDateTime):TDateTime; var Datei, LastDate, LastLinie: ShortString; sl, zellen: TStringList; i: Integer; tmpStr: ShortString; ADOCommand: TADOCommand; begin while DateToStr(LastTime) <> DateToStr(now+1) do begin Datei := Pfad + '\' + DateToStr(LastTime) + '.txt'; if FileExists(Datei) then begin sl := TStringList.Create; zellen := TStringList.Create; zellen.Delimiter:=';'; sl.LoadFromFile(Datei); AdoCommand := TAdoCommand.Create(nil); AdoCommand.ConnectionString := Form1.ADOConnection1.ConnectionString; for i:=0 to sl.Count-1 do begin try tmpStr := TrimAll(sl[i]); zellen.DelimitedText := tmpStr; AdoCommand.CommandText := 'INSERT INTO BGRScan (TraceNr, Datum, LinieID) VALUES (' + zellen[1] + ', :Datum,' + zellen[0] + ')'; if (LastDate <> copy(zellen[2], 1, 10) + ' ' + copy(zellen[2], 11, 8)) or (LastLinie <> zellen[0]) then begin LastDate := copy(zellen[2], 1, 10) + ' ' + copy(zellen[2], 11, 8); LastLinie := zellen[0]; AdoCommand.Parameters.ParamByName('Datum').Value := LastDate; AdoCommand.Execute; end; except
end; end; end; LastTime := incDay(LastTime); end; end;
procedure Trace.Execute; var check, checkModule: Boolean; ADOCommand: TADOCommand; tmpDateTime: TDateTime; tmpStr, pfad: ShortString; i, Anzahl: Integer; begin CoInitialize(nil); AdoCommand := TAdoCommand.Create(nil); AdoCommand.ConnectionString := Form1.ADOConnection1.ConnectionString; check := true; while check = true do begin checkModule := false; i := INI_ReadInt('Module', '1', 0); if i = 1 then checkModule := true; if checkModule = false then begin i := INI_ReadInt('Module', '1', 0); if i = 1 then checkModule := true; end; if checkModule = true then begin tmpStr := INI_ReadString('TraceKonverter', 'Zeit', '01.11.2007 12:00:00'); tmpDateTime := Datenuebertragung(ExtractFilePath(ParamStr(0)) + 'ScanDaten', StrToDateTime(tmpStr)); tmpStr := DateTimeToStr(tmpDateTime); INI_WriteString('TraceKonverter', 'Zeit', tmpStr); end else check := false;
checkModule := false; i := INI_ReadInt('Module', '3', 0); if i = 1 then checkModule := true; if checkModule = true then begin check := true; Anzahl := INI_ReadInt('TraceKonverter', 'Anzahl', 0); for i:=1 to Anzahl do begin pfad := INI_ReadString('TraceKonverter', 'SubnetzPfad' + IntToStr(i), ''); if DirectoryExists(pfad) then begin tmpStr := INI_ReadString('TraceKonverter', 'SubnetzZeit' + IntToStr(i), '01.11.2007 12:00:00'); tmpDateTime := Datenuebertragung(pfad, StrToDateTime(tmpStr)); tmpStr := DateTimeToStr(tmpDateTime); INI_WriteString('TraceKonverter', 'SubnetzZeit' + IntToStr(i), tmpStr); end else FehlerProtokoll('Der Pfad bei der Subnetzübertragung "' + IntToStr(i) + '" stimmt nicht. Pfad: ' + pfad); end; end; tmpDateTime := GetSchichtEnde(now); sleep(MilliSecondsBetween(now, tmpDateTime)); Form1.ListBox1.Clear; Form1.ListBox2.Clear; Form1.Label8.Caption := DateTimeToStr(now); end; Form1.Label8.Caption := 'deaktiviert'; Form1.Label5.Font.Color := clGray; Form1.Label8.Font.Color := clGray; end;
end. |
_________________ Es gibt keine dummen Fragen nur dumme Antworten!!!
|
|
Bronstein 
      
Beiträge: 578
Erhaltene Danke: 1
WIN XP
Delphi 6 / Delphi 2006 / Delphi XE
|
Verfasst: Sa 10.11.07 13:14
Hat sich erledigt, ich habe ausversehen den Thread zweimal gestartet!
_________________ Es gibt keine dummen Fragen nur dumme Antworten!!!
|
|
Gausi
      
Beiträge: 8549
Erhaltene Danke: 478
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Sa 10.11.07 13:17
Trotzdem solltest du dringend die VCL-Zugriffe aus dem Thread entfernen! Ein Thread, der an der Form rumfummelt, kann zwar manchmal funktionieren, aber meistens fährt der zwischen durch vor nen Baum oder schlimmeres. Sowas muss man per Synchronize erledigen.
_________________ We are, we were and will not be.
|
|
Bronstein 
      
Beiträge: 578
Erhaltene Danke: 1
WIN XP
Delphi 6 / Delphi 2006 / Delphi XE
|
Verfasst: So 11.11.07 00:52
Und wenn ich den Thread mit BeginThread starte, kann ich dann am Form1 etwas ändern?
_________________ Es gibt keine dummen Fragen nur dumme Antworten!!!
|
|
Lossy eX
      
Beiträge: 1048
Erhaltene Danke: 4
|
Verfasst: So 11.11.07 01:50
Na ja. Ein Thread bleibt ein Thread. Und TThread benutzt intern auch nur BeginThread. Allerdings bietet es gleich schon solche Dinge wie Synchronize. Das müsstest du bei BeginThread per Hand machen. Und du solltest generell aus Threads nicht auf die VCL zugreifen. Denn die VCL ist nicht Threadsafe. Denn wenn du gerade etwas änderst und im Hintergrund eine WindowsMessage reinkommt dann greifen 2 Stellen gleichzeit auf ein und die selben Objekte zu. Das muss zwar keine Probleme geben aber dadurch, dass du etwas schreibst ist die Wahrscheinlichkeit nicht klein. Also wie Gausi sagt. Besser immer mit Synchronize, denn in Messages können die Objekte nun auch verändert werden.
_________________ Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
|
|
gispos
      
Beiträge: 94
WIN 7
XE10, D2007
|
Verfasst: So 11.11.07 03:07
Hallo bronstein,
habe ein paar Fehler in deinem Code gefunden.
Bei der function Datenuebertragung erstellst Du 2 StringListen, die aber nirgends
freigegeben werden! Gewöhne Dir an nach einem Create Object ein Try finally
mit einzubauen!
Delphi-Quelltext 1:
| i:= INI_ReadInt('Module', '1', 0); |
checkModule kannste Dir sparen, und Du wiederholst sogar mehrmals Deine
Frage nach checkModule. Machs so:
Delphi-Quelltext 1: 2: 3: 4:
| If INI_ReadInt('Module', '1', 0) = 1 then Begin End; |
Ich finde auch nirgends ein Try except , gerade in einem Thread ist das wichtig!
Gruß gispos
Moderiert von Christian S.: Delphi-Tags hinzugefügt
|
|
Bronstein 
      
Beiträge: 578
Erhaltene Danke: 1
WIN XP
Delphi 6 / Delphi 2006 / Delphi XE
|
Verfasst: So 11.11.07 07:43
@Lossy eX
Wie funktioniert das mit dem Synchronize, bei den Labels sehe ich keine Probleme, denn die werden nur zur Statusanzeige verwendet (sprich nur der Thread greift darauf zu). Bei den Listboxen ist das nicht der Fall, denn die werden von Main über ein Edit OnChange Ereignis gefüllt.
@gispos
Danke, das mit den Stringlisten hatte ich vergessen.
Bei checkModule, hatte ich bei der zweiten Abfrage einen Fehler, denn da wollte ich nach Modul2 fragen:
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: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129:
| function Datenuebertragung(Pfad: ShortString; LastTime: TDateTime):TDateTime; var Datei, tmpTime, LastLinie: ShortString; sl, zellen: TStringList; i: Integer; tmpStr: ShortString; ADOCommand: TADOCommand; begin tmpTime := DateTimeToStr(LastTime); while DateToStr(LastTime) <> DateToStr(now+1) do begin Datei := Pfad + '\' + DateToStr(LastTime) + '.txt'; if FileExists(Datei) then begin sl := TStringList.Create; zellen := TStringList.Create; zellen.Delimiter:=';'; sl.LoadFromFile(Datei); AdoCommand := TAdoCommand.Create(nil); AdoCommand.ConnectionString := Form1.ADOConnection1.ConnectionString; for i:=0 to sl.Count-1 do begin try tmpStr := TrimAll(sl[i]); zellen.DelimitedText := tmpStr; if zellen[0] <> '0' then begin AdoCommand.CommandText := 'INSERT INTO BGRScan (TraceNr, Datum, LinieID) VALUES (' + zellen[1] + ', :Datum,' + zellen[0] + ')'; if (tmpTime <> copy(zellen[2], 1, 10) + ' ' + copy(zellen[2], 11, 8)) or (LastLinie <> zellen[0]) then begin tmpTime := copy(zellen[2], 1, 10) + ' ' + copy(zellen[2], 11, 8); if StrToDateTime(tmpTime) > LastTime then begin LastLinie := zellen[0]; AdoCommand.Parameters.ParamByName('Datum').Value := tmpTime; AdoCommand.Execute; end; end; end; except FehlerProtokoll('Fehler bei der Subnetzübertragung: Vermutlich ist die Datenbank zur Zeit nicht verfügbar'); end; end; sl.Free; zellen.Free; end; LastTime := incDay(LastTime); end; result := StrToDateTime(tmpTime); end;
procedure Trace.Execute; var check, checkModule: Boolean; tmpDateTime: TDateTime; tmpStr, pfad: ShortString; i, Anzahl: Integer; begin try CoInitialize(nil); tmpStr := INI_ReadString('Einstellungen', 'DBPfad',tmpStr); if FileExists(tmpStr) then begin check := true; while check = true do begin checkModule := false; i := INI_ReadInt('Module', '1', 0); if i = 1 then checkModule := true; if checkModule = false then begin i := INI_ReadInt('Module', '2', 0); if i = 1 then checkModule := true; end; if checkModule = true then begin tmpStr := INI_ReadString('TraceKonverter', 'Zeit', '01.11.2007 12:00:00'); tmpDateTime := Datenuebertragung(ExtractFilePath(ParamStr(0)) + 'ScanDaten', StrToDateTime(tmpStr)); tmpStr := DateTimeToStr(tmpDateTime); INI_WriteString('TraceKonverter', 'Zeit', tmpStr); end else check := false;
checkModule := false; i := INI_ReadInt('Module', '3', 0); if i = 1 then checkModule := true; if checkModule = true then begin check := true; Anzahl := INI_ReadInt('TraceKonverter', 'Anzahl', 0); for i:=1 to Anzahl do begin pfad := INI_ReadString('TraceKonverter', 'SubnetzPfad' + IntToStr(i), ''); if DirectoryExists(pfad) then begin tmpStr := INI_ReadString('TraceKonverter', 'SubnetzZeit' + IntToStr(i), '01.11.2007 12:00:00'); tmpDateTime := Datenuebertragung(pfad, StrToDateTime(tmpStr)); tmpStr := DateTimeToStr(tmpDateTime); INI_WriteString('TraceKonverter', 'SubnetzZeit' + IntToStr(i), tmpStr); end else FehlerProtokoll('Der Pfad bei der Subnetzübertragung "' + IntToStr(i) + '" stimmt nicht. Pfad: ' + pfad); end; end; tmpDateTime := GetSchichtEnde(now); Form1.ListBox1.Clear; Form1.ListBox2.Clear; Form1.Label8.Caption := DateTimeToStr(now); sleep(MilliSecondsBetween(now, tmpDateTime)); end; end; Form1.Label8.Caption := 'keine Verbindung zur Datenbank, Daten werden lokal gespeichert'; Form1.Label5.Font.Color := clGray; Form1.Label8.Font.Color := clGray; Form1.Label8.Color := Form1.Color; except FehlerProtokoll('Fehler beim Trace-Thread'); end; end; |
_________________ Es gibt keine dummen Fragen nur dumme Antworten!!!
|
|
Lossy eX
      
Beiträge: 1048
Erhaltene Danke: 4
|
Verfasst: So 11.11.07 18:44
@Bronstein: Lass dich bitte nicht davon verleiten, dass dort nichts passiert weil du da nichts machst. Wenn es neu gezeichnet werden muss etc dann wird da auch drauf zugegriffen. Also besser immer sichern.
Und zu synchronize. Schau mal da. Und im Zwiefel sollte bei so etwas die Delphihilfe immer erster Anlaufpunkt sein.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| TMyOwnThread = class(TThread) private procedure SyncTuWas; end;
implementation
procedure TMyOwnThread.SyncTuWas; begin end;
procedure TMyOwnThread.Execute; begin Synchronize(SyncTuWas); end; |
_________________ Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
|
|
Bronstein 
      
Beiträge: 578
Erhaltene Danke: 1
WIN XP
Delphi 6 / Delphi 2006 / Delphi XE
|
Verfasst: Mo 12.11.07 00:02
Diese Antwort bringt mich nicht wirklich weiter, villeicht kannst du mir ein Bsp. zu meinem Fall geben!
_________________ Es gibt keine dummen Fragen nur dumme Antworten!!!
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mo 12.11.07 03:12
In SyncTuWas kommen deine VCL-Zugriffe rein. Ggf. brauchste davon mehrere Methoden ...
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Bronstein 
      
Beiträge: 578
Erhaltene Danke: 1
WIN XP
Delphi 6 / Delphi 2006 / Delphi XE
|
Verfasst: Mi 14.11.07 21:34
Könnte ich dann nicht meinen kompletten Code den ich im Execute habe in die Funktion SyncTuWas kopieren, oder ist es besser wenn ich nur diese Dinge in die Funktion kopiere:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| Form1.ListBox1.Clear; Form1.ListBox2.Clear; Form1.Label8.Caption := DateTimeToStr(now); end; end; Form1.Label8.Caption := 'keine Verbindung zur Datenbank, Daten werden lokal gespeichert'; Form1.Label5.Font.Color := clGray; Form1.Label8.Font.Color := clGray; Form1.Label8.Color := Form1.Color; |
_________________ Es gibt keine dummen Fragen nur dumme Antworten!!!
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Do 15.11.07 14:38
In die synchronisierten Routinen gehört nur der VCL-basierte Code.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
gispos
      
Beiträge: 94
WIN 7
XE10, D2007
|
Verfasst: Do 15.11.07 21:28
@bronstein > Habe noch ein paar Try's eingebaut.
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:
| function Datenuebertragung(Pfad: ShortString; LastTime: TDateTime):TDateTime; var Datei, tmpTime, LastLinie: ShortString; sl, zellen: TStringList; i: Integer; tmpStr: ShortString; ADOCommand: TADOCommand; begin tmpTime := DateTimeToStr(LastTime); sl := TStringList.Create; zellen := TStringList.Create; zellen.Delimiter:=';'; Try while DateToStr(LastTime) <> DateToStr(now+1) do begin Datei := Pfad + '\' + DateToStr(LastTime) + '.txt'; if FileExists(Datei) then begin Try sl.LoadFromFile(Datei); except FehlerProtokoll('Kann Datei nicht laden: '+ Datei); exit; Continue; end; AdoCommand := TAdoCommand.Create(nil); AdoCommand.ConnectionString := Form1.ADOConnection1.ConnectionString; for i:=0 to sl.Count-1 do begin try tmpStr := TrimAll(sl[i]); zellen.DelimitedText := tmpStr; if zellen[0] <> '0' then begin AdoCommand.CommandText := 'INSERT INTO BGRScan (TraceNr, Datum, LinieID) VALUES (' + zellen[1] + ', :Datum,' + zellen[0] + ')'; if (tmpTime <> copy(zellen[2], 1, 10) + ' ' + copy(zellen[2], 11, 8)) or (LastLinie <> zellen[0]) then begin tmpTime := copy(zellen[2], 1, 10) + ' ' + copy(zellen[2], 11, 8); if StrToDateTime(tmpTime) > LastTime then begin LastLinie := zellen[0]; AdoCommand.Parameters.ParamByName('Datum').Value := tmpTime; AdoCommand.Execute; end; end; end; except FehlerProtokoll('Fehler bei der Subnetzübertragung: Vermutlich ist die Datenbank zur Zeit nicht verfügbar'); exit; end; end; end; LastTime := incDay(LastTime); end; finally result := StrToDateTime(tmpTime); sl.Free; zellen.Free; end; end; |
Gruß gispos
|
|
Bronstein 
      
Beiträge: 578
Erhaltene Danke: 1
WIN XP
Delphi 6 / Delphi 2006 / Delphi XE
|
Verfasst: Sa 17.11.07 22:04
Ich danke allen, hat mir sehr viel gebracht. Werde das Programm jetzt mal ausgibig testen!
_________________ Es gibt keine dummen Fragen nur dumme Antworten!!!
|
|
|