DOBON.NET DOBON.NETプログラミング掲示板過去ログ

フォームのマルチスレッドで

環境/言語:[Windows XP .NET Dremework 1.1]
分類:[.NET]

C#でEXCEL帳票を作成するクラスを作成し、その中で処理中を表示するフォームをスレッドで実装しました。
フォーム内でTimerクラスを使用し、処理中をブリンクさせるようにしているのですが、タイマーイベントでApplication.DoEvents();を記述すると、XPだとWIN32エラーとなります。
2000だと問題なく正常終了します。
タイマーイベント内でApplication.DoEvents();をコメントにすれば、エラーにはなりません。
何が悪いのでしょうか。

[** 帳票クラス **]
//スレッドオブジェクトを生成します
Thread dialogThread = new Thread(new ThreadStart(DialogThreadStart));
//スレッドを開始します
dialogThread.Start();

private void DialogThreadStart()
{
//処理中画面(frmShoriCh.cs)をNewします
this._runDialog = new frmShoriCh();
//処理中画面を表示します
this._runDialog.ShowDialog();
}

private void DialogThreadEnd()
{
if (this._runDialog!=null)
{
//フォームを閉じます
this._runDialog.Close(); → この処理が終わったあとにWIN32エラーとなる。
}

[** フォームクラス **]
private void _timer_Tick(object sender, EventArgs e)
{
//処理中メッセージの反転
label1.Visible = !label1.Visible;
label2.Visible = !label2.Visible;
Application.DoEvents(); → コメントにするとエラーにならない。
}
いわっちさん、こんにちは

当方XP-ProにてC#で同様のアプリを組んでみましたが、エラーは起こりませんでした。

他のコードの影響かもしれませんね。 とりあえず、最小規模でのアプリを作ってエラー原因を特定していくのがよいかと思います。

あと、ラベルの表示更新のためにDoEventを呼んでいるのかと思いますが、フォームのRefreshもしくは、ラベルのRefreshでも大丈夫かと思います。
フォームは全て親のフォームのスレッドから表示しなければ
内部の整合性が保たれなくなりエラーになります。

子スレッド→親クラスのデリゲート(又はイベント)をIvoke
→呼ばれた先の親クラス関数内でダイアログを表示/閉じる

また、Application.DoEvent()は表示以外のイベントも処理してしまう為、
アプリのほかの部分の動作に悪影響を与える事が多いです。
イベントを子スレッドで処理する場合は、表示イベント等必要なイベントのみを
PeekMessageで取り出して処理した方が安全です。
■No4710に返信(てすてすさんの記事)
> フォームは全て親のフォームのスレッドから表示しなければ
> 内部の整合性が保たれなくなりエラーになります。
>
> 子スレッド→親クラスのデリゲート(又はイベント)をIvoke
> →呼ばれた先の親クラス関数内でダイアログを表示/閉じる
>
> また、Application.DoEvent()は表示以外のイベントも処理してしまう為、
> アプリのほかの部分の動作に悪影響を与える事が多いです。
> イベントを子スレッドで処理する場合は、表示イベント等必要なイベントのみを
> PeekMessageで取り出して処理した方が安全です。

windowsプログラム初心者なのですが
PeekMessageをc#で使用するには、WIN32APIを使用する必要があるのでしょうか。
それとも、dllで公開されているのでしょうか。
どのdllを使用したらようかわからず。
■No4709に返信(ゆさんの記事)
> いわっちさん、こんにちは
>
> 当方XP-ProにてC#で同様のアプリを組んでみましたが、エラーは起こりませんでした。
>
> 他のコードの影響かもしれませんね。 とりあえず、最小規模でのアプリを作ってエラー原因を特定していくのがよいかと思います。
>
> あと、ラベルの表示更新のためにDoEventを呼んでいるのかと思いますが、フォームのRefreshもしくは、ラベルのRefreshでも大丈夫かと思います。
>
>

Refreshで試してみました、エラーにはなりませんどした。
他のスレッドでフォームを表示しているので、画面はかたまらないので
DoEventを発行する必要はないのですね。
■No4713に返信(いわっちさんの記事)
> ■No4709に返信(ゆさんの記事)
>>いわっちさん、こんにちは
>>
>>当方XP-ProにてC#で同様のアプリを組んでみましたが、エラーは起こりませんでした。
>>
>>他のコードの影響かもしれませんね。 とりあえず、最小規模でのアプリを作ってエラー原因を特定していくのがよいかと思います。
>>
>>あと、ラベルの表示更新のためにDoEventを呼んでいるのかと思いますが、フォームのRefreshもしくは、ラベルのRefreshでも大丈夫かと思います。
>>
>>
>
> Refreshで試してみました、エラーにはなりませんどした。
> 他のスレッドでフォームを表示しているので、画面はかたまらないので
> DoEventを発行する必要はないのですね。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板