Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 访问线程中的vcl组件!德尔菲_Multithreading_Delphi - Fatal编程技术网

Multithreading 访问线程中的vcl组件!德尔菲

Multithreading 访问线程中的vcl组件!德尔菲,multithreading,delphi,Multithreading,Delphi,所以,我的目标是在另一个线程中启动一个函数。我还需要从新线程访问其他vcl组件。以下是我目前的代码: procedure TForm1.StartButtonClick(Sender: TObject); var thread1: integer; id1: longword; begin thread1 := beginthread(nil,0,Addr(Tform1.fetchingdata),nil,0,id1); closehandle(thread1); end; pr

所以,我的目标是在另一个线程中启动一个函数。我还需要从新线程访问其他vcl组件。以下是我目前的代码:

procedure TForm1.StartButtonClick(Sender: TObject);
var
thread1: integer;
id1: longword;
begin
   thread1 := beginthread(nil,0,Addr(Tform1.fetchingdata),nil,0,id1);
    closehandle(thread1);
end;

procedure TForm1.FetchingData;
var
  ...
begin
  Idhttp1.IOHandler := IdSSLIOHandlerSocketOpenSSL1;   //<- error
  idhttp1.Request.ContentType := 'application/x-www-form-urlencoded';
程序TForm1.StartButtonClick(发送方:TObject);
变量
thread1:整数;
id1:长单词;
开始
thread1:=beginthread(nil,0,Addr(Tform1.fetchingdata),nil,0,id1);
闭柄(螺纹1);
结束;
程序TForm1.FetchingData;
变量
...
开始

Idhttp1.IOHandler:=IdSSLIOHandlerSocketOpenSSL1// VCL(Gui组件)只能从主线程访问。其他线程需要主线程来访问VCL。

AV的原因是您将
TForm
方法的地址传递给需要
TThreadFunc
的函数(请参阅)。像这样使用
Addr()
是防止编译器指出错误的好方法

您需要做的是编写一个具有正确签名的包装器函数,将表单实例作为参数传递,然后从该函数调用表单上的方法


但不要这样做,要么将代码作为
TThread
的后代编写,要么(最好)使用更高级别的包装器,如或。并确保不在主线程中访问VCL组件,在工作线程中创建并释放所需的组件。

如果使用Delphi或Lazarus,您可以在常规的TThread中尝试同样的方法

    type
          TSeparateThread = class(TThread)
            private
            protected
            public
              constructor Create(IfSuspend: Boolean);
              proceedure Execute; override;
            // variables to fill go here
            // s : String;
            // i : Integer;
            // etc...
          end;

        constructor TSeparateThread.Create(IfSuspend: Boolean);
        begin
          inherited Create(IfSuspend);    
        end;

        procedure TSeparateThread.Execute;
        begin

  // This is where you will do things with those variables and then pass them back.

        YourMainUnitOrForm.PublicVariableOf := s[i];

  // passes position 0 of s to PublicVariableOf in your Main Thread

        end;
调用新线程的操作如下所示:

with TSeparateThread.Create(true) do
  begin

  // This is where you fill those variables passed to the new Thread
          s := 'from main program';
          i := 0;
  // etc...

    Resume; 

  //Will Start the Execution of the New Thread with the variables filled.

  end;

实现这一点的简单方法是,次要线程发布WM_用户消息,主线程响应这些消息。但是,在您的情况下,使用indy Tid防冻剂可能会达到相同的效果。阅读此
http://stackoverflow.com/questions/37185/whats-the-idiomatic-way-to-do-async-socket-programming-in-delphi