2010-11-23 5 views
2

だから、私の目標は、別のスレッドで関数を開始しています。また、私は新しいスレッドから他のvclコンポーネントにアクセスする必要があります。ここに私のコードは、これまでです:スレッド内の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'; 

私のプログラムがハングし、私はエラーを取得:00154E53のモジュールmy.exeで例外EAccessViolation。モジュール 'my.exe'のアドレス00554E53のアクセス違反。アドレスの前に00000398.

感謝を読みます。

答えて

9

AVの原因は、メソッドのアドレスを、TThreadFuncdocumentation of System.BeginThread()を参照)が必要な関数に渡すことです。このようなAddr()を使用すると、バグを指摘からコンパイラを保つための良い方法です。あなたが代わりに行う必要があるだろう何

は、正しいシグネチャを持つラッパー関数を記述するパラメータとしてフォームのインスタンスを渡すと、その関数からフォーム上のメソッドを呼び出すことです。

TThreadの子孫としてコードを書くか、AsyncCallsOmni Thread Libraryのような上位ラッパーを(できれば)使用してください。また、メインスレッドのVCLコンポーネントにアクセスしないようにして、ワーカースレッドで必要なものを作成して解放してください。

5

VCL(GUIコンポーネント)は唯一メインスレッドからアクセスされます。他のスレッドはVCLにアクセスするためにメインスレッドを必要とします。

+1

をし、これを実現する簡単な方法は、WM_USERメッセージを投稿し、二次スレッドとそれらへの対応メインスレッドです。しかし、あなたの場合、indy TidAntiFreezeオブジェクトを使用することで同じ効果を得ることができます。 // stackoverflow.com /質問/ 37185 /いただきまし--慣用ウェイ・ツー・ドゥー・非同期ソケット・プログラミング・イン・delphi':この 'HTTPを読みます –

0

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; 
関連する問題