![]() |
Thread Error
Hallöchen,
ich hab ein programm das bis vor kurzem noch auf dem PC lief. Nachdem ich es nun auf dem Schlepptop kopiert habe, alles neu erzeugt und kompliziert habe, kommt es zum folgenden Fehler. Thread Error: Der Parameter stimmt nicht (87) Dies passiert wenn ich auf den Beenden Button klicke. In dem seiner Proz. steht nur Close;, sonst nichts. klicke ich die Meldung weg und dann nochmal auf Beenden, so wird das Programm normal beendet. Beim Kompliozieren gibt es weder Hinweise, noch Meldungen. Was will mir der Fehler mitteilen?. Vielen Dank. Grüsse, Daniel :hi: |
:?:
Hast Du irgendwelche Sonderheiten im Programm (z.B. Multi-Thread), ist ja immerhin ein Threadfehler... ...:cat:... |
Delphi-Quellcode:
unit Hauptformular;
interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Menus, CPort, StdCtrls, Buttons, Einstellungen, Info, Inifiles; type TForm1 = class(TForm) GroupBox1: TGroupBox; GroupBox2: TGroupBox; ComPort: TComPort; MainMenu: TMainMenu; ButtonSX0auf0: TButton; ButtonSX1auf0: TButton; ButtonSX0auf1: TButton; ButtonSX1auf1: TButton; Datei: TMenuItem; Extras: TMenuItem; MenueEinstellungen: TMenuItem; Hilfe1: TMenuItem; MenueHilfe: TMenuItem; N1: TMenuItem; MenueInfo: TMenuItem; GroupBox3: TGroupBox; BitBtnEin: TBitBtn; BitBtnAus: TBitBtn; BitBtnSX0und1auf0: TBitBtn; BitBtnBeenden: TBitBtn; MenueBeenden: TMenuItem; MenueNeustart: TMenuItem; BitBtnSX0und1auf1: TBitBtn; procedure FormShow(Sender: TObject); procedure BitBtnEinClick(Sender: TObject); procedure BitBtnAusClick(Sender: TObject); procedure BitBtnSX0und1auf0Click(Sender: TObject); procedure BitBtnSX0und1auf1Click(Sender: TObject); procedure MenueNeustartClick(Sender: TObject); procedure MenueEinstellungenClick(Sender: TObject); procedure MenueInfoClick(Sender: TObject); procedure ButtonSX0auf0Click(Sender: TObject); procedure ButtonSX1auf0Click(Sender: TObject); procedure ButtonSX0auf1Click(Sender: TObject); procedure ButtonSX1auf1Click(Sender: TObject); procedure BitBtnBeendenClick(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; CPPort: string; CPBaud: string; // CPForm: string; implementation {$R *.dfm} procedure TForm1.FormShow(Sender: TObject); //Befehle die beim Start ausgeführt werden var ini: TIniFile; begin if not (FileExists('SXSETZER.ini')) then //wenn die Datei noch nicht angelegt ist begin ini := TIniFile.Create(ChangeFileExt(ParamStr(0), '.ini')); try //Standardwerte schreiben ini := TIniFile.Create(ChangeFileExt(ParamStr(0), '.ini')); ini.WriteString('Einstellungen', 'Port', 'COM1'); ini.WriteString('Einstellungen', 'Baud', '9600'); // ini.WriteString('Einstellungen', 'Format', '2'); CPPort := ini.ReadString('Einstellungen', 'Port', ''); //Standardwerte lesen und setzen CPBaud := ini.ReadString('Einstellungen', 'Baud', ''); // CPForm := ini.ReadString('Einstellungen', 'Format', ''); finally ini.Free; //Datei schliessen/freigeben end; end else if FileExists('SXSETZER.ini') then //falls Datei schon vorhanden begin ini := TIniFile.Create(ChangeFileExt(ParamStr(0), '.ini')); try //Werte lesen CPPort := ini.ReadString('Einstellungen', 'Port', ''); CPBaud := ini.ReadString('Einstellungen', 'Baud', ''); // CPForm := ini.ReadString('Einstellungen', 'Format', ''); finally ini.Free; //Datei schliessen/freigeben end; end; BitBtnBeenden.SetFocus; ComPort.Port := CPPort; //ComPort Port setzen ComPort.CustomBaudRate := StrToInt(CPBaud); //ComPort BaudRate setzen ComPort.Open; end; procedure TForm1.BitBtnEinClick(Sender: TObject); //Gleis EIN begin ComPort.WriteStr(#255#128); end; procedure TForm1.BitBtnAusClick(Sender: TObject); //Gleis AUS begin ComPort.WriteStr(#255#0); end; procedure TForm1.BitBtnSX0und1auf0Click(Sender: TObject); //SX0 und SX1 auf 0 setzen begin ComPort.WriteStr(#114#2); end; procedure TForm1.BitBtnSX0und1auf1Click(Sender: TObject); //SX0 und SX1 auf 1 setzen var i: integer; begin for i := 128 to 231 do begin ComPort.WriteStr(#254#0 + chr(i) + #255); ComPort.WriteStr(#254#1 + chr(i) + #255); end; end; procedure TForm1.MenueNeustartClick(Sender: TObject); //Neustart der Zentrale begin ComPort.WriteStr(#114#0); end; procedure TForm1.MenueEinstellungenClick(Sender: TObject); //Das Einstellungen-Fenster öffnen begin Einst.ShowModal; end; procedure TForm1.MenueInfoClick(Sender: TObject); //Das Info-Fenster öffnen begin About.ShowModal; end; procedure TForm1.ButtonSX0auf0Click(Sender: TObject); //Adressen 0 - 103 bei SX0 auf 0 setzen var i: integer; begin for i := 128 to 231 do begin ComPort.WriteStr(#254#0 + chr(i) + #0); end; end; procedure TForm1.ButtonSX1auf0Click(Sender: TObject); //Adressen 0 - 103 bei SX1 auf 0 setzen var i: integer; begin for i := 128 to 231 do begin ComPort.WriteStr(#254#1 + chr(i) + #0); end; end; procedure TForm1.ButtonSX0auf1Click(Sender: TObject); //Adressen 0 - 103 bei SX0 auf 1 setzen var i: integer; begin for i := 128 to 231 do begin ComPort.WriteStr(#254#0 + chr(i) + #255); end; end; procedure TForm1.ButtonSX1auf1Click(Sender: TObject); //Adressen 0 - 103 bei SX1 auf 1 setzen var i: integer; begin for i := 128 to 231 do begin ComPort.WriteStr(#254#1 + chr(i) + #255); end; end; procedure TForm1.BitBtnBeendenClick(Sender: TObject); begin ComPort.Close; Close; end; end. |
Zitat:
Ansonsten kann ich keine Probleme erkennen. |
Was willst du eigentlich mit
Zitat:
|
Zitat:
Ich hab noch ein bisschen rumgespielt. Es hat was mit dem ComPort schliessen zutun. Jetzt wo alles im BitBtnClick drin ist, passiert es nur noch wenn ich es über den Menüpunkt beende. Wenn ich aber das CP.Close; in der OnClose drin habe, passiert es auch wenn ich auf den Button klicke. Grüsse, Daniel :hi: |
Zitat:
Grüsse, Daniel :hi: |
Moin Daniel B,
solche Aufräumarbeiten beim Beenden sollten, zur Sicherheit, immer in's OnDestroy des Formulares. OnClose und OnCloseQuery werden bei Application.Terminate nicht aufgerufen. |
Hallo Christian,
und wo ist der unterschied, ob ich mit Close und OnClose arbeite, oder mit Terminate und OnDestroy? Grüsse, Daniel :hi: |
Moin Daniel,
wenn Du immer sicherstellst, dass OnClose auch aufgerufen wird ist der gibt's eigentlich keinen Unterschied. Solltest Du aber auch nur mal ein Formular dynamisch erzeugen, und mit Free wieder freigeben hast Du den Salat, wenn Du Deine Aufräumarbeiten im OnClose erledigen willst. Das wird dann nämlich auch nicht aufgerufen. Wenn man immer genau aufpasst, dass die belegeten Resourcen immer wieder sauber freigegeben werden spielt der Zeitpunkt natürlich keine Rolle, an dem das geschieht. Ich halte es allerdings für eine Verringerung der Fehlerwahrscheinlichkeit, wenn man sich für so etwas an Stellen gewöhnt, die bei einem normalen Programmablauf auch garantiert aufgerufen werden. Soll heissen: Werden Resourcen belegt (z.B. durch Create, so es sich denn nicht um eine Komponente mit Angabe des Owners handelt), gehört als nächstes ein try/finally Block gesetzt. Oder Resourcen werden in OnCreate/OnDestroy bzw. initialization/finalization Paaren belegt/freigegeben. Es mag natürlich immer mal Ausnahmen von der Regel geben, aber wo dieses nicht zwingend notwendig ist, halte ich es für sinnvoll diese Regeln für saubere Programme einzuhalten. Manchmal kann man auch feststellen, dass man ein strukturelles Problem mit seinem Programm hat, wenn sich so eine Regel nicht einhalten lässt. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:49 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