定时器进程影响delphi中的用户界面

pra*_*aba 2 delphi background timer delphi-7

我开发了读卡器读取信息的应用程序.在这里,我使用计时器每五秒获取一次信息,因此每五秒钟用户界面变慢,因为它从读者那里获取信息.如何在后台运行计时器而不影响用户界面

unit frmVistorreg;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms;

type
 thread1=class(TThread)
 private
 FEvent: THandle;
 protected
 procedure Execute; override;
 public
 procedure MyTerminate;
end;


TForm3 = class(TForm)     
txt_name: TEdit;   
txt_cardno.Text  TEdit;        

private

public

end;

var
Form3: TForm3;

implementation

{$R *.dfm}


procedure thread1.Execute;
var
idcard_info :array[0..1024*5] of byte;
flag :Integer;
portflag :Integer;
st :TStrings;
str :string;  
begin

FEvent:= CreateEvent(nil, False, false, nil);
try
while not Terminated do begin
if  MainForm.PortFlag=0 then
begin

 Form3.Label11.Caption:='port has been successfully opened';
 Form3.Label11.Font.Color :=32768;
 flag := GetIdCardInfo(@idcard_info[0],1024*5,5);
 str := byteArray2Str(@idcard_info[0],1024*5);

        if(flag=0) then
        begin
           st := TStringList.Create;
           try
              SplitStr('^_^',str,st);
              Form3.txt_name.Text := st.Strings[0]; 
              Form3.txt_cardno.Text := st.Strings[5]; 
          finally
        st.Free;
          end;
        end;

end
else
begin 

Form3.Label11.Caption:='Please open the port';
Form3.Label11.Font.Color:=clRed;
end;

if WaitForSingleObject(FEvent, 500) <> WAIT_TIMEOUT // 5 seconds timeout
then Terminate;
end;

finally
CloseHandle(FEvent);
end;
end;


procedure thread1.MyTerminate;
begin
 SetEvent(FEvent);
end;


procedure TForm3.FormClose(Sender: TObject; var Action: TCloseAction);
var
Objthread1:thread1;
begin   
Objthread1.MyTerminate;
Action := caFree;
end;


procedure TForm3.FormCreate(Sender: TObject);
var
Objthread1:thread1;
begin
Objthread1:=thread1.Create(false);  
end;

end.
Run Code Online (Sandbox Code Playgroud)

当我关闭表单时有错误

Project MDIAPP.exe raised exception class EAccessViolation with message 'Access violation at address 0051B9F1 in module 'MDIAPP.exe'. Read of address 00000198'.
Run Code Online (Sandbox Code Playgroud)

我怎么能解决这个问题.

klu*_*udg 10

你不需要一个计时器组件,你需要一个后台线程.最简单的解决方案是Sleep在线程中使用函数:

unit Unit2;

interface

uses
  Classes;

type
  TMyThread = class(TThread)
  protected
    procedure Execute; override;
  end;

implementation

procedure TMyThread.Execute;
begin
  while not Terminated do begin
// do your processing here
    Sleep(5000);   // wait 5 seconds
  end;
end;

end.
Run Code Online (Sandbox Code Playgroud)

更好的方法是使用WaitForSingleObject和事件而不是Sleep能够在没有5秒延迟的情况下立即终止后台线程:

unit Unit2;

interface

uses
  Windows, Classes;

type
  TMyThread = class(TThread)
  private
    FEvent: THandle;
  protected
    procedure Execute; override;
  public
    procedure MyTerminate;
  end;

implementation

procedure TMyThread.Execute;
begin
  FEvent:= CreateEvent(nil, False, False, nil);
  try
    while not Terminated do begin
// do your processing here
// ..
      if WaitForSingleObject(FEvent, 5000) <> WAIT_TIMEOUT // 5 seconds timeout
        then Terminate;
    end;
  finally
    CloseHandle(FEvent);
  end;
end;

procedure TMyThread.MyTerminate;
begin
  SetEvent(FEvent);
end;

end.
Run Code Online (Sandbox Code Playgroud)

TMyThread表单的事件处理程序关闭表单调用MyTerminate方法时终止实例OnClose.

是的,知道你收到的错误信息很有趣,而不仅仅是"显示错误".

  • 请详细了解错误.说明"显示错误"并不是很有帮助.看起来好像你甚至懒得花5秒钟粘贴相应的错误信息,但后来希望我们通过一些魔法过程来解决错误信息. (4认同)