2010-11-23 8 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의 원인은 TForm 메서드의 주소를 TThreadFunc (예상되는 함수)으로 전달한다는 것입니다 (documentation of System.BeginThread() 참조). 이처럼 Addr()을 사용하면 컴파일러가 버그를 지적하지 못하게하는 좋은 방법입니다.

올바른 서명이있는 래퍼 함수를 ​​작성하고 매개 변수로 폼 인스턴스를 전달하고 해당 함수의 폼에서 메서드를 호출하면됩니다.

그러나 코드를 TThread의 자손으로 작성하거나 AsyncCalls 또는 Omni Thread Library과 같은 상위 수준의 래퍼를 사용하는 것이 좋습니다. 그리고 주 스레드에서 VCL 컴포넌트에 액세스하지 말고, 작업자 스레드에서 필요한 것들을 생성하고 해제하십시오.

5

VCL (Gui 구성 요소)은 주 스레드에서만 액세스 할 수 있습니다. 다른 스레드는 VCL에 액세스하기 위해 주 스레드가 필요합니다.

+1

이는 WM_USER 메시지와 그들에게 응답 메인 스레드를 게시 보조 스레드입니다 달성 할 수있는 쉬운 방법을 다음과 같이

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; 

는 새로운 스레드가 완료 호출. 그러나 귀하의 경우에는 indy TidAntiFreeze 객체를 사용하여 동일한 효과를 얻을 수 있습니다. 이'http : // stackoverflow.com/questions/37185/whats-the-idiomatic-way-to-do-async-socket-in-delphi'을 읽으십시오. –

0

Delphi 또는 나사로를 사용하는 경우 일반 TThread로 동일한 작업을 시도 할 수 있습니다.

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; 
관련 문제