C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: マルチスレッドで lock がうまくかかりません。


(過去ログ 30 を表示中)

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■14630 / inTopicNo.1)  マルチスレッドで lock がうまくかかりません。
  
□投稿者/ のぶ (15回)-(2008/02/24(Sun) 07:30:32)

分類:[.NET 全般] 

度々お世話になってます。

早速、質問させていただきます。

メインのスレッドで複数個のBitmap生成し、あるタイミングでDraw系のメソッドで描画処理を行っています。
それと同時に別スレッドでも、メインのスレッドに対し「書き込みせよ」のイベントを発生させ描画の処理をさせているのですが

--------------------------------------------
オブジェクトは現在他の場所で使用されています
ヒント:GetHDC メソッドの後にグラフィックスオブジェクトを使用する場合、ReleaseHdcメソッドを呼び出してください。
--------------------------------------------
と怒られてしまいます。

はじめは

--------------------------------------
  lock (g)    ← は Graphics.FromImage(Bitmap) より取得した Graphics オブジェクト
  {
    g.DrawString("xxxx");
  }
---------------------------------------

で駄目だったので、次は static 変数で現在処理中を判断するための bool Drawing の変数を用意し
以下のようにしてみました。

---------------------------------------
while (obj.Drawing) { System.Threading.Thread.Sleep(100); } // drawが終了するまでループ
obj.Drawing = true;
try
{
    lock (g)
    {
      g.DrawString("xxxx");
    }
}
finally
{
    obj.Drawing = false;
}
----------------------------------------

やっぱり駄目でした。orz

lock の使用方法(考え方)が間違っているのでしょうか?
Bitmap複数個使用しているのが問題なんでしょうかねぇ・・
エラーになる時とならない時があるので解決できず困っています。

よろしくお願いします。

引用返信 編集キー/
■14631 / inTopicNo.2)  Re[1]: マルチスレッドで lock がうまくかかりません。
□投稿者/ 倉田 有大 (138回)-(2008/02/24(Sun) 09:34:48)
>メインのスレッドに対し「書き込みせよ」のイベントを発生させ描画の処理をさせているのですが

メインのフォームに描画したいのですか?
だとすると、フォームを作成したスレッドで書かないと駄目ですよ。
Invoke関連かな?

あまり質問を正確に把握してないかもしれません。
引用返信 編集キー/
■14641 / inTopicNo.3)  Re[2]: マルチスレッドで lock がうまくかかりません。
□投稿者/ やじゅ (181回)-(2008/02/24(Sun) 14:32:16)
やじゅ さんの Web サイト
■のぶ さん に返信

>System.Threading.Thread.Sleep(100); } // drawが終了するまでループ
これの考えが微妙な気がする

メモリ上に下記2つを用意
@画像の生成が完了
A画像の生成を生成中
あるタイミングで、画像の生成が完了したものを描画する。

画像の生成は裏側(メモリ)上で生成する。
裏側(メモリ)上で画像生成が完了したら、完了側メモリに転送する。

ロックするとしたら、完了側メモリに転送している間くらいかな。
引用返信 編集キー/
■14643 / inTopicNo.4)  Re[3]: マルチスレッドで lock がうまくかかりません。
□投稿者/ 囚人 (286回)-(2008/02/24(Sun) 15:49:05)
C# の lock ステートメントはクリティカルセクションです。

たぶん、
lock(g)
とやったときに、g 自身がロックされると勘違いされているのではないでしょうか?


class Clazz{
	private static object syncobj = new object();

	public void Func1(){
		lock(syncobj){
			// コード1
		}
	}

	public void Func2(){
		lock(syncobj){
			// コード2
		}
	}
}

lock は上記のようにやれば、「コード1」を実行中に「コード2」が実行される事はありません、という使い方です。
当然ですけど、まったく同じオブジェクトをロックしなければなりませんよ。

引用返信 編集キー/
■14657 / inTopicNo.5)  Re[2]: マルチスレッドで lock がうまくかかりません。
□投稿者/ のぶ (16回)-(2008/02/25(Mon) 01:40:28)
No14631 (倉田 有大 さん) に返信
> >メインのスレッドに対し「書き込みせよ」のイベントを発生させ描画の処理をさせているのですが
>
> メインのフォームに描画したいのですか?
> だとすると、フォームを作成したスレッドで書かないと駄目ですよ。
> Invoke関連かな?

コメントありがとうございます。m(__)m
描画はメインフォームではなく、クラス内に持ったBitmapに対しての描画です。
別スレッドから、直接描画するのはまずいのかと思い、一応、ビットマップを持っている
クラスに対してイベントを発生させて描画させておりましたが駄目でした。。。

が、囚人さんのコメントにより解決することが出来ました。

また、なにかありましたらよろしくお願いいたします。m(__)m




引用返信 編集キー/
■14658 / inTopicNo.6)  Re[3]: マルチスレッドで lock がうまくかかりません。
□投稿者/ のぶ (17回)-(2008/02/25(Mon) 01:45:57)
No14641 (やじゅ さん) に返信

コメントありがとうございます。m(__)m

> >System.Threading.Thread.Sleep(100); } // drawが終了するまでループ
> これの考えが微妙な気がする

やはりそうですか・・・・
static 変数でdraw中かどうかのフラグをもって終了するのをまてば
エラーは起きないかと思い、浅はかな考えでやってみました(^^;
どうやら、lock の使い方を勘違いしていたのが原因でした。

ありがとうございました。

引用返信 編集キー/
■14659 / inTopicNo.7)  Re[4]: マルチスレッドで lock がうまくかかりません。
□投稿者/ のぶ (18回)-(2008/02/25(Mon) 02:04:06)
コメントありがとうございます。

No14643 (囚人 さん) に返信
> C# の lock ステートメントはクリティカルセクションです。
> たぶん、
> lock(g)
> とやったときに、g 自身がロックされると勘違いされているのではないでしょうか?

全くその通りの勘違いをしていました(^^;
g をlockすれば、他の箇所で使用しても lockした元の処理が終了するまで待ってくれるのかと思っておりました(>_<)

drawする前に static にもったobjectで lock をかけると無事解決できました!

> 当然ですけど、まったく同じオブジェクトをロックしなければなりませんよ。
以前のソースは graphic(1),graphic(2),graphic(3)・・・ と各々lockしてたので
デバイスコンテキストが競合(?)してしまうんですね。。
(表現が怪しい・・・)

ありがとうございました。m(__)m

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -