- PR -

プログレスバーが再描画されない

1
投稿者投稿内容
ぺそまる
会議室デビュー日: 2004/10/01
投稿数: 14
投稿日時: 2007-05-25 19:42
重い処理を別スレッドで実行している間、プログレスバーを表示しようと思い、
以下のようなコードを書きました。

.NET Framework 1.1
Windowsアプリケーション(C#)
Form1にボタン(button1)とプログレスバー(progressBar1)を貼り付け。

コード:
private void button1_Click(object sender, System.EventArgs e) {
	// 重い処理を実行
	Thread trd = new Thread(new ThreadStart(this.ThreadTask));
	trd.IsBackground = true;
	trd.Start();

	progressBar1.Minimum = 1;
	progressBar1.Maximum = 10;
	bool flag = true;
	while (flag) {
		for (int ii = progressBar1.Minimum; ii <= progressBar1.Maximum; ii++) {
			if (!trd.IsAlive) {
				flag = false;
				break;
			}
			progressBar1.Value = ii;
			this.Update();
			Thread.Sleep(1000);
		}
	}

	MessageBox.Show("終わりました。");
}

private void ThreadTask() {
	// 重い処理のつもり
	Thread.Sleep(15000);
}



通常はbutton1をクリックするとプログレスバーが進むのですが、
Form1をマウスでドラッグすると、プログレスバーが再描画されなくなり、
重い処理が終わったタイミングで再描画されます。
同じような現象になった方、回避策などあればご教示ください。
ぶさいくろう
ぬし
会議室デビュー日: 2005/11/22
投稿数: 1232
お住まい・勤務地: 川崎市(は俺も含めてロクな人間が住んでないよw)
投稿日時: 2007-05-25 19:47
引用:

ぺそまるさんの書き込み (2007-05-25 19:42) より:
重い処理を別スレッドで実行している間、プログレスバーを表示しようと思い、
以下のようなコードを書きました。

.NET Framework 1.1
Windowsアプリケーション(C#)
Form1にボタン(button1)とプログレスバー(progressBar1)を貼り付け。

コード:
private void button1_Click(object sender, System.EventArgs e) {
	// 重い処理を実行
	Thread trd = new Thread(new ThreadStart(this.ThreadTask));
	trd.IsBackground = true;
	trd.Start();

	progressBar1.Minimum = 1;
	progressBar1.Maximum = 10;
	bool flag = true;
	while (flag) {
		for (int ii = progressBar1.Minimum; ii <= progressBar1.Maximum; ii++) {
			if (!trd.IsAlive) {
				flag = false;
				break;
			}
			progressBar1.Value = ii;
			this.Update();
			Thread.Sleep(1000);
		}
	}

	MessageBox.Show("終わりました。");
}

private void ThreadTask() {
	// 重い処理のつもり
	Thread.Sleep(15000);
}



通常はbutton1をクリックするとプログレスバーが進むのですが、
Form1をマウスでドラッグすると、プログレスバーが再描画されなくなり、
重い処理が終わったタイミングで再描画されます。
同じような現象になった方、回避策などあればご教示ください。


なんでUpdateのみ?Invalidateは?
ぺそまる
会議室デビュー日: 2004/10/01
投稿数: 14
投稿日時: 2007-05-25 20:31
Invalidate、Updateの順に呼び出してみましたが、
状況は変わりませんでした。
ちなみに、Refreshも試したのですが、同じでした。

Invalidateメソッドを知らなかったので、勉強になりました。
回答ありがとうございました。
IIJIMAS
ベテラン
会議室デビュー日: 2006/12/06
投稿数: 77
投稿日時: 2007-05-25 21:09
Application.DoEvents メソッド
http://msdn2.microsoft.com/ja-jp/library/system.windows.forms.application.doevents(VS.80).aspx
はやってみましたか?

参考サイト:
@IT > Insider.NET > .NET TIPS > 時間がかかる処理での「応答なし」を回避するには?
http://www.atmarkit.co.jp/fdotnet/dotnettips/136doevents/doevents.html

DOBON.NET > プログラミング道 > .NET Tips > その他のTips > 時間のかかる処理の進行状況を表示する
http://dobon.net/vb/dotnet/programing/displayprogress.html
ぺそまる
会議室デビュー日: 2004/10/01
投稿数: 14
投稿日時: 2007-05-25 21:42
Refreshの後にApplication.DoEventsメソッドを呼び出すようにしたところ、
再描画されるようになりました。
ご紹介いただいた参考サイトのうち、DOBON.NETの方は読んでいたのですが、
DoEventsかスレッド化のどちらか二者択一だと勝手に思い込んでいたため、
スレッド化した時点でDoEventsは不要だと思ってしまっていました。
残りのサイトについても、もう一度じっくり読み直して、きちんと理解したいと思います。
回答ありがとうございました。
取り急ぎ、結果報告まで。
1

スキルアップ/キャリアアップ(JOB@IT)