2017-04-05 2 views
2

Delphi XE3でBeginThreadを使用すると、機能がブロックされます。何故ですか?BeginThread delphiのブロック機能

私は以下の問題の最小限のバージョンを作成しようとしました。 2つのボタンが押されている場合は、ボタンbtn1を押すとbtn1のキャプションが 'nooo'に変わります。 btn2が押された場合、btn1キャプションが 'yesss'に変更されます。

btn1が押されると、BeginThreadを使って永久にループするスレッドも開始します。

問題は次に、btn1.Caption:= 'nooo'です。 BeginThreadブロック以降は決して元に戻されません。 Shouled私はbtn1.Captionに達する:= 'nooo';

unit Unit1; 

interface 

uses 
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, 
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; 

type 
    TForm1 = class(TForm) 
    btn1: TButton; 
    btn2: TButton; 
    procedure btn1Click(Sender: TObject); 
    procedure btn2Click(Sender: TObject); 

    private 
    function test() : Integer; 
    { Private declarations } 
    public 

    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

function TForm1.test() : Integer; 
begin 

    while True do 
    begin 
     Sleep(Random(1000) * 2); 
    end; 
    Result := 0; 
end; 

procedure TForm1.btn1Click(Sender: TObject); 
var 
    id: LongWord; 
begin 
    BeginThread(nil, 0, Pointer(test), nil, 0, id); 
    btn1.Caption := 'nooo'; 
end; 

procedure TForm1.btn2Click(Sender: TObject); 
begin 
    btn1.Caption := 'yesss'; 
end; 

end. 
+0

使用のTThreadクラスとあなたの時間を無駄に 'tを! –

+0

あなたのキャストはコンパイラにあり、価格を支払うことになります。 –

+0

デバッグのヒント: 'BeginThread'行にブレークポイントを設定してください。ブレークポイントに達すると、メソッドに入るために 'F7 'を押します。あなたは、問題の手がかりになるはずの 'test'メソッドに直接入ります。 –

答えて

7

発現Pointer(test)コールtest()、次いでPointerに結果を入力は、キャスト。 test()は返さないので、キャストする結果はありません。したがって、BeginThread()に渡す値はありません。 BeginThread()自体はブロックされません。最初に呼び出されることはありません。

BeginThread()の3番目の引数は、タイプがPointerではありません。タイプTThreadFuncであり、これは1つのPointer引数を受け取り、Integerを返すスタンドアロン(非メンバー)関数です。 TForm1.test()メソッドはスタンドアロン機能ではないため、修飾されません。

test()は、スタンドアロン機能も作り、その後、(任意の型キャストまたは@オペレータなし)BeginThread()に直接渡します。代わりに

function test(param: Pointer): Integer; 
begin 
    while True do 
    Sleep(Random(1000) * 2); 
    Result := 0; 
end; 

var 
    id: LongWord; 
begin 
    BeginThread(nil, 0, test, nil, 0, id); 
end; 
+2

それ以外の場合は、代わりに 'BeginThread()'を内部的に使用する 'TThread'クラスを使用してください。 –

関連する問題