我在一个form中定义了一个public的myDBTable
并且我在form创建的时候,给它赋值了。然后我想在一个线程中使用,结果无法访问。请教原因定义部分public
    myDBTable,myDBTable1:TDAMemDataTable; //就是要用这个myDBTable
    yjbh,Waittime1:integer;
    yjmc:string;
    yjdx,yjfs:Integer;
    function NeedSave : boolean; override;
    { Public declarations }
  end;var
  EXPERIForm: TEXPERIForm;
  hloopHandle:Thandle ;              //线程 句柄
  dloopThreadID:DWORD ;              //线程 id
  CS:TRTLCriticalSection;
  lpHandles:Thandle;
  lpTheradID:DWORD;线程部分://线程处理函数一
procedure doloop(P:pointer);stdcall;
var
  i:Integer;
begin
  with EXPERIForm.myDBTable do begin    //这一句报错,无法访问
    while not eof do begin
      EnterCriticalSection(CS);
      Sleep(25);
      try
        if (EXPERIForm.yjmc<>fieldbyName('yjmc').AsString)  or
           (EXPERIForm.yjbh<>fieldbyName('yjbh').AsInteger) or
           (EXPERIForm.yjdx<>fieldbyName('yjdx').AsInteger) or
           (EXPERIForm.yjfs<>fieldbyName('yjfs').AsInteger) then  begin          EXPERIForm.yjmc:=fieldbyName('yjmc').AsString;   //元件名称
          EXPERIForm.yjbh:=fieldbyName('yjbh').AsInteger;   //元件编号
          EXPERIForm.yjdx:=fieldbyName('yjdx').AsInteger;  //元件字节长度
          EXPERIForm.yjfs:=fieldbyName('yjfs').AsInteger;  //操作方式
        end;        if COM_ReadFromPLC(EXPERIForm.yjmc,EXPERIForm.yjbh,EXPERIForm.yjdx,EXPERIForm.yjfs)then begin
          Next;
        end;
        Sleep(15);
      finally
        LeaveCriticalSection(CS);
      end;
    end;
  end;
end;
谢谢

解决方案 »

  1.   

    移动一下位置:
    var
      
      myDBTable,myDBTable1:TDAMemDataTable; //就是要用这个myDBTable
      

  2.   

    在线程内定义一个变量x:TDAMemDataTable,创建线程时就传myDBTable进去赋值给X; x:=myDBTable
      

  3.   

    改成这样还出错啊//线程处理函数一
    procedure doloop(P:pointer);stdcall;
    var
      i:Integer;
      mytbl:TDAMemDataTable;
    begin
      mytbl:= EXPERIForm.myDBTable;   //这一句出错,无法访问
      with mytbl do begin
      

  4.   

    EXPERIForm 没有初赋值,当然没有办法访问了。
      

  5.   

    EnterCriticalSection(CS);
    这句应该提到徇环外面,执行一次就够了。
      

  6.   

    procedure TEXPERIForm.stBtnClick(Sender: TObject);
    begin
      
      hloopHandle:= CreateThread(nil,0,@doloop,nil,0,dloopThreadID);
      if hloopHandle=0 then
      begin
        messagebox(Handle,'Didn’t Create a Thread',nil,MB_OK);
        abort;
      end;
    end;我是这样启动一个线程的,怎么传值进去?我定义了
    //线程处理函数一
    procedure doloop(P:pointer;mytbl:TDAMemDataTable);stdcall;
    var
      i:Integer;
    begin
      //mytbl:= Synchronize(EXPERIForm.myDBTable);
      with mytbl do begin      EnterCriticalSection(CS);
          Sleep(25);
          try
            while not eof do begin
    。谢谢
      

  7.   

    function CreateThread(
      lpThreadAttributes: Pointer;           {安全设置}
      dwStackSize: DWORD;                    {堆栈大小}
      lpStartAddress: TFNThreadStartRoutine; {入口函数}
      lpParameter: Pointer;                  {函数参数}
      dwCreationFlags: DWORD;                {启动选项}
      var lpThreadId: DWORD                  {输出线程 ID }
    ): THandle; stdcall;                     {返回线程句柄}
    入口函数 Delphi 的 System 单元定义的是: TThreadFunc = function(Parameter: Pointer): Integer;
    也就是说你这个函数不合格
    建议继承 TThread来定义一个新线程,然后在创建线程时给它的属性赋值,在 excute方法里执行你指定的方法。Delphi线程入门,参看万一的博客  
      

  8.   

    线程 我已经勉强建好了,还是有几个问题请教:1   我在线程中调用了一个 程序的公共函数,为什么不能在公共函数中使用 sleep(100),这个函数?一使用就是报错2  线程怎样修改 程序 中的公共变量?谢谢
      

  9.   

    其实线程调用一般函数没有问题,但是你要搞清楚调用的东西是否与线程相关。像基于com的一些控件,调用他们的函数时就会出错。
    sleep函数与线程没有什么关系吧,我经常那么用的。
      

  10.   

    建议还是用继承TThread方式建立新线程类吧,如果sleep报错的话是不是没有调用sysutils单元的原因导致的。