メインスレッドに処理が重い個所がありフォームがフリーズしたように見えてしまいます。そこでTThreadクラスを使い処理中メッセージを表示させ現象を回避しようとしましたが問題が発生しました。
メインスレッドからTThreadを実装したクラスのインスタンスを作成するのですがメインスレッドのイベント終了待ちをしてしまい思うようにメッセージを表示することができません。何か良い手はないでしょうか?
///////メインスレッド/////////
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls, Unit2, Unit4;
type
TForm1 = class(TForm)
Label1: TLabel;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
MyThread : TMyThread2;
TForm4:TForm4;
procedure MyThreadDone(Sender: TObject);
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
begin
Label1.caption := 'スレッド処理始まり';
MyThread := TMyThread2.Create(False);
MyThread.OnTerminate := MyThreadDone;
//重い処理
for i := 0 to 100 do
begin
sleep(20);
end;
MyThread.FormExit();
MyThread.Terminate();
end;
procedure TForm1.MyThreadDone(Sender: TObject);
begin
//ShowMessage('End');
Label1.caption := 'スレッド処理終わり';
end;
end:
///////サブスレッド/////////
unit Unit4;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, ComCtrls, StdCtrls;
type
TMyThread2 = class(TThread)
private
{ Private 宣言 }
form1:TForm;
protected
procedure Execute; override;
public
procedure FormExit;
end;
type
TForm4 = class(TForm)
ProgressBar1: TProgressBar;
Label1: TLabel;
Label2: TLabel;
procedure FormClick(Sender: TObject);
private
{ Private 宣言 }
MeThread1 :TThread;
public
{ Public 宣言 }
end;
var
Form4: TForm4;
implementation
{$R *.dfm}
procedure TMyThread2.Execute;
var
i : integer;
begin
try
form1 := Tform4.Create(nil);
form1.ShowModal();
finally
form1.Release;
end;
end;
procedure TMyThread2.FormExit();
begin
form1.ModalResult := 99;
end;
【補足】
メインスレッドがサブスレットのインスタンスを握っているため?にそれぞれのスレッドが独立して動きません(Botton1処理がすべて終了するまでサブスレッドは動きません)。処理のイメージとしてはサブスレットがCreateされた時点で画面に処理中フォームが作成され重たい処理が終了したらメインスレッドからサブスレッドのフォーム、スレッドの順で削除を行います。
サブスレッドはフォームをShowModalで表示するためそこで処理待機状態になっていると考えています。
長くなってしまいましたがご教授よろしくお願いします。
環境を書き忘れていました。
実行環境はDelphi2010です。
とりあえず、スレッドについて勉強したほうがよろしいかと。
「スレッドセーフ」って単語も知っておいたほうが良いです。
ちなみにスレッドはDelphiに限った話では無いので、とりあえず言語問わずでざっくり学んだ方が近道かもです。
目的は違いますが、スレッドを使ったサンプルをちょっと前に投稿してあります。2番目の投稿
https://www.petitmonte.com/bbs/answers?question_id=7629
私もこれで良いのかかなり心配してます…
回答ありがとうございます。
ご指摘された通り前知識が少ない状態で検証サンプルを作っていました、、
上がっている単語とURLのサンプルを読み解いてもう一度作りなおしてみます。
その後また質問することがあるかもしれませんが、その時またよろしくお願いします。
ツイート | ![]() |