unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids;const
MyMessage =WM_USER+101;type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure AddStrPro(Var Message:TMessage);message MyMessage;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  Form1: TForm1;
  ThreadID:DWORD;
  ThreadHandle:THandle;
  :Boolean=True;
  t:Integer=1;
implementation{$R *.dfm}
function DataRecv(p: Pointer): DWORD; stdcall;
var i:Integer;
begin
  while True do
  begin
    SendMessage(Form1.Handle,MyMessage,1,1);
    if Mark=False then
    Break;
  end;
end;procedure TForm1.AddStrPro(var Message: TMessage);
var
i:Integer;
begin
;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
  ThreadHandle:= CreateThread(nil, 0, @DataRecv, nil, 0, ThreadID);
end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  :=False;
  //这里怎么写才能安全退出呢
  Action:=caFree;
end;end.
老是内存出错,要不就死锁。

解决方案 »

  1.   

    SendMessage 改成 PostMessage 
      

  2.   

    除了这个呢。。postmessage要进队列,会与主线程其他的队列消息竞争
      

  3.   

    这个是TThread类中的吧,我现在不是直接API创建的线程嘛
      

  4.   

    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      :=False;
      //这里怎么写才能安全退出呢
      Action:=caFree;
    end;你加个断点测下,看关闭时候没执行到 
      

  5.   

    你觉得会不会有这样的情况,当PeekMessage取得退出消息的时候wm_close,这时另个线程sendmessage,那么这时sendmessage就不会返回了
      

  6.   

    那在close中怎么等呢,如果我用了WaitForSingleObject的话就容易出现互锁,昨天还问过这样的问题
      

  7.   

    {我没测试过,也没在Delphi里编写,可能存在未知错误}
    var 
      hThread: THandle;function DataRecv(p: Pointer): DWORD; stdcall;
    var i:Integer;
    begin
      while True do
      begin
        SendMessage(Form1.Handle,MyMessage,1,1);
        if Mark=False then
        Break;
      end;
      Result := 99; {这个返回值将成为线程的退出代码, 99 是我随意给的数字}
    end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    var
      ExitCode: DWORD;
    begin  try    :=False;
        Action:=caFree;  finally
        
        GetExitCodeThread(hThread, ExitCode);
        {如果那个线程里的程序很重要,那么这样的等待它执行完成}
        {否则直接结束线程吧}
        {如果线程没有退出, GetExitCodeThread 获取的退出码将是一个常量}    {STILL_ACTIVE (259); 这样我们就可以通过退出码来判断线程是否已退出.}
        while (hThread<>0) and (ExitCode = STILL_ACTIVE) then
        begin
          sleep(100);
          GetExitCodeThread(hThread, ExitCode);
        end;    end;
    end;