スレッド実行中にメインフォームをコントロールするには?

解決


スレッダー中尉  2009-12-04 22:20:50  No: 36395

メインフォーム(Unit1.pas)からボタンを押して
スレッド(Unit2.pas)を呼び出して実行します。

Unit2.pasではfor等では置き換えられない単独で
時間のかかる処理を行います。
(今回はsleepで代用しました。)

この時、メインフォームはボタンを押してから
sleepが終わるまでコントロールできなくなります。
これを回避するにはどうしたらいいでしょうか?

TURBO DELPHIです。

■Unit1.pasの内容
//----------------------------------------------------
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,Unit2, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
    thread: MyThread;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
   thread:=MyThread.Create(False);
end;

end.
//----------------------------------------------------

■Unit2.pasの内容
//----------------------------------------------------
unit Unit2;

interface

uses
  Windows,Classes,Dialogs;

type
  MyThread = class(TThread)
  private
    { Private 宣言 }
  protected
    procedure Execute; override;
    procedure Todo;
  end;

implementation

{ MyThread }

procedure MyThread.Execute;
begin
  { TODO: スレッドとして実行したいコードをここに記述してください }
  Synchronize(Todo);
end;

procedure MyThread.Todo;
begin
 sleep(10000);
 showmessage('end');
end;

end.
//----------------------------------------------------


そのワケは  2009-12-04 23:06:43  No: 36396

Synchronizeメソッドをヘルプで確認してね。


その  2009-12-04 23:07:18  No: 36397

> Synchronize(Todo);
はTodoをメインスレッドで実行するということだから、スレッドに分けた意味なくない?

「スレッドとして実行したいコードをここに記述してください」というコメントのところにスレッドとして実行したいコードを記述して、
Synchronizeするのは同期が必要なところ(最後のshowmessage)だけにしないと。


スレッダー中尉  2009-12-04 23:36:19  No: 36398

回答ありがとうございました。
ググってポトペタな私は、
コンポーネントの衝突を避けるためには
Synchronizeメソッドで行えば安全なんだからと
(確かに安全です)本来の意味も考えずに
使用してしまいました。
お恥ずかしい限りです。
ありがとうございました!


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加