マルチスレッドにするには?

解決


うに  2012-05-30 18:29:50  No: 42387

メインスレッドに処理が重い個所がありフォームがフリーズしたように見えてしまいます。そこで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で表示するためそこで処理待機状態になっていると考えています。

長くなってしまいましたがご教授よろしくお願いします。


うに  2012-05-30 18:32:17  No: 42388

環境を書き忘れていました。
実行環境はDelphi2010です。


monaa  2012-05-30 19:02:47  No: 42389

とりあえず、スレッドについて勉強したほうがよろしいかと。
「スレッドセーフ」って単語も知っておいたほうが良いです。
ちなみにスレッドはDelphiに限った話では無いので、とりあえず言語問わずでざっくり学んだ方が近道かもです。

目的は違いますが、スレッドを使ったサンプルをちょっと前に投稿してあります。2番目の投稿
https://www.petitmonte.com/bbs/answers?question_id=7629
私もこれで良いのかかなり心配してます…


うに  2012-05-31 18:15:18  No: 42390

回答ありがとうございます。
ご指摘された通り前知識が少ない状態で検証サンプルを作っていました、、

上がっている単語とURLのサンプルを読み解いてもう一度作りなおしてみます。
その後また質問することがあるかもしれませんが、その時またよろしくお願いします。


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

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






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