- PR -

スレッドからデリゲートでフリーズ

投稿者投稿内容
otf
ベテラン
会議室デビュー日: 2006/08/04
投稿数: 91
投稿日時: 2007-12-10 22:31
簡略的に書くにしても疑似コードはやめてほしい。

とりあえずコードBのWaitOne,ReleaseMutexはkokodetumaruメソッドの中に書くべきだと
思います。
ReleaseMutexはfinallyで確実に呼ばれるようにしてください。

>なのでMutexってそのコードファイル全体をブロック
>しちゃうのでこれって正常動作なんでしょうか?
言っている意味がよくわかりません。
排他制御を行うときは大抵メソッド内でMutexの取得、解放が完結すると思います。

>それでコードBにkokodetumaru()を記述したところ
>問題が解消されました。
スレッド関係は発生度稀なバグを作ることが多いので
一時、問題が発生しなくなったからといって解決したとは思わない方がいいでしょう。
未記入
大ベテラン
会議室デビュー日: 2005/08/25
投稿数: 145
投稿日時: 2007-12-10 22:40
すいません。解決していませんでした。
さっきは問題なかったのですが
今やってみたらまたもや同様の問題が発生しました。

ただ、前に比べるとフリーズする頻度は下がったようには思えるのですが
どなたかアドバイスいただければありがたいです。
れい
ぬし
会議室デビュー日: 2005/11/01
投稿数: 346
投稿日時: 2007-12-10 22:53
引用:

未記入さんの書き込み (2007-12-10 22:40) より:
どなたかアドバイスいただければありがたいです。


otfさんをはじめ皆さんアドバイスしてますよ。
無視せずきちんと人の話を聞きましょう。

とりあえず、コードが意味不明です。

テキストボックスを使うなら、
親フォームのクラス・作成元スレッドの情報もないとわかりません。

いい加減なものを投稿するのではなく、
他人が読んでわかるように抜粋し、投稿したほうがいいと思います。
未記入
大ベテラン
会議室デビュー日: 2005/08/25
投稿数: 145
投稿日時: 2007-12-11 18:59
otfさん書き込みが互い違いになってしまいまして申し訳ないです。
症状が発生するコードを書きましたのでこちらでご確認お願いします。
このコードを書いてボタンを連打するとフリーズします。

コードA
delegate void del();
private Mutex mut = new Mutex();

private void timer1_Tick(object sender, EventArgs e)//100ms 間隔が短いほうが症状が発生しやすいです
{
mut.WaitOne();

//テキストボックスが多ければ多いほど起こりやすいです。
textBox1.Text = "0";
textBox2.Text = "0";




textBox99.Text = "0";
textBox100.Text = "0";

mut.ReleaseMutex();
}

private void dainyu()
{
textBox1.Text = "1";
textBox2.Text = "1";



textBox99.Text = "1";
textBox100.Text = "1";
}
-------------------------------------------------------------------
コードB
private void button1_Click(object sender, EventArgs e)
{
Thread threadA = new Thread(new ThreadStart(abc));
threadA.Start();
}

private void abc()
{
mut.WaitOne();

Invoke(new del(dainyu));

mut.ReleaseMutex();
}
-------------------------------------------------------------------

それとMutexの位置は他のプログラムとの兼ね合いからずらせないです。
このコードでフリーズしてしまう原因がおわかりになる方
いらっしゃいましたら教えていただけると幸いです。

なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2007-12-11 19:20
ちょっと冷静に追えばすぐに分かると思いますよ。

button1_Click

abc開始

Mutex取得

Invokeでdainyu呼び出し

この時点で、Mutexを取得したままでInvokeしています。
つまり、Mutexを取得したままUIのスレッドを待っています。

UIのスレッドが空いていていればいいですが、
この時微妙なタイミングでtimer1_Tickが発生すると、

Mutex取得待ち
でUIのスレッドが止まります。

UIのスレッドはMutexが開放されない限り動けませんが、
別のスレッドがMutexを取得したままUIスレッドの空きを待っているので
永久にストップします(デッドロック)。
未記入
大ベテラン
会議室デビュー日: 2005/08/25
投稿数: 145
投稿日時: 2007-12-11 19:54
なちゃさん。ありがとうございました。
謎がやっと解けました。

UIのスレッドがあるのですか。
UIのスレッドってつまり普通のというかメインの処理も
1つのスレッドとうい事なんですよね。
そういうことですよね?
間違っていたら訂正していただければありがたいです。

対処方法としましてはタイマーのところをスレッドにして
ぐるぐる回すということにすればデッドロックにならないのでは
ないかと考えております。

また何かありましたらよろしくお願いします。

[ メッセージ編集済み 編集者: 未記入 編集日時 2007-12-11 21:03 ]
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-12-12 07:10
Invoke の説明に、そのようなことが書いてありませんでしたか?

解決策は、ミューテックスをロックするまえに、タイマーを一時停止すればいいでしょう。解放後、再開します。

タスクマネージャーで、プロセスがいくつスレッドを起動しているかを見ることができます

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