共享线程的公共属性

时间:2018-05-08 16:32:34

标签: delphi thread-safety

我的类继承自TThread,具有多个属性,其中一个是TAdoDataSet。我的线程创建自己的TAdoConnection和TAdoDataSet。我的问题是: 1-在MyThread终止后主线程中使用DataSet(MyThread.dataset)是否安全? 2-是否有更好的技术来实现这一要求?我的意思是,创建一个打开数据集然后在主线程中使用数据集的线程? CAllBack功能还是PostMessage?

TmyProc =Procedure (Msg:TmyMsg) of object;

  TmyThread = Class(TThread)
  private
    FConnection: TAdoConnection;
    FMyDataset :TAdoDataSet;
    FmyProc: TMyProc;
  protected
    procedure Execute; override;
    property myProc: TmyProc read FmyProc;
  public
    Constructor Create(myProc:TmyProc;
                      ConnectionString: WideString);
    property MyDataSet: TAdoDataSet read FMyDataset 
  end;

constructor TmyThread .Create(Susp:Boolean; myProc:TmyProc; 
   ConnectionString: WideString);
begin

// here I create the connection and mydataset;
// and my callback comes from main thread;
FmyProc := myProc; 

inherited Create(Susp);
end;


procedure TmyThread.Execute;
begin
  inherited;
  CoInitialize(nil);
  // here I open the connection and myDataset
  CoUninitialize();
end;


In the main thread :

procedure TForm1.Button1Click(Sender: TObject);
begin
  mt:=TmyThread.Create(True,ACallBack,ADOConnection1.ConnectionString);
  mt.FreeOnTerminate := True;
  mt.OnTerminate:= OnThredDone;
  mt.Resume;
end;

3-正如您在上面的代码中看到的那样,freeonterminate:= True,但当我使用以下方法测试MyThread时,MyThread保持活动状态:if Assigned(MyThread)。

1 个答案:

答案 0 :(得分:0)

这不是线程安全的。在Delphi中调用

已分配(MyThread)

仅测试零。它与

相同

nil<> MyThread的

但是,在Delphi中,在对象上调用Free不会将对象指针设置为nil。

MyThread.Free;
if Assigned(MyThread) then  //this will return true
begin
  MyThrerad.MyDaSet.First; //and this will give you an access violation!
end;

Delphi有一个内置的FreeAndNil过程,可确保将对象指针设置为nil。人们应该使用它。