|
なるほど…やはりフォームAとフォームBは同一スレッドで起動すべきなんですね…
ちなみに、現在の状態を、究極までシンプルにしたソースは以下のとおりです。
----------
using System;
using System.Windows.Forms;
using System.Threading;
namespace FormTest
{
// FormA
public partial class FormA : Form
{
public FormA()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// 時間のかかるメイン処理を別スレッドで起動
Thread threadA = new Thread(new ThreadStart(MainFunc));
threadA.Start();
}
delegate void label_Set_Delegate(string msg);
private void label1_Set_Delegate(string msg)
{
label1.Text = msg;
label1.Update();
}
private void MainFunc()
{
for (int i = 0; i <= 9; i++)
{
// 処理中のプロセス番号を表示
Invoke(new label_Set_Delegate(label1_Set_Delegate), new object[] { i.ToString() });
// ある条件でFormBを起動
if ((i & 1) == 0) // 仮に偶数のとき
{
FormB subForm = new FormB(i);
subForm.ShowDialog();
}
}
}
}
// FormB
public partial class FormB : Form
{
private int proc;
public FormB(int i)
{
InitializeComponent();
proc = i;
}
private void Form2_Shown(object sender, EventArgs e)
{
this.Text = proc.ToString(); // フォームのタイトルにプロセス番号を表示
progressBar1.Minimum = 0;
progressBar1.Maximum = 9;
Update();
for (int i = 0; i <= 9; i++)
{
// 処理状況をプログレスバーで表示
progressBar1.Value = i;
Thread.Sleep(200);
}
// 終了したらフォームを閉じる
this.Close();
}
}
}
----------
フォームAで行いたい処理(MainFunc)自体が、フォームAとは別スレッドになっていて、そのMainFuncからフォームBを起動しています。
「フォームAとフォームBを同一スレッドにする」ということは、MainFuncからのフォーム作成はNGということでしょうか?
フォームBが起動するのは「MainFuncが必要としたタイミング」なので、
どうしてもMainFuncから起動すること(すなわちフォームAとは別スレッド)になってしまうのですが…。
また、イベントを使う件ですが、外部関数の進捗状況は、stdoutに出力されたテキストを
フォームBが都合のよいタイミングで取得しているだけなので、イベント受け渡しにするのは難しいかと思っています。
|