- - PR -
.net2005 C# BackgroundImageをオーバーライドするとOutOfMemoryになってしまいます
投稿者 | 投稿内容 |
---|---|
|
投稿日時: 2007-05-13 13:47
囚人さん
ありがとうございます。 また格闘してましたが、やはり解決できませんでした。トレースでは以下のとおりです。 深そうですので、長期になると思います。 解決しましたら、改めて報告したいと思います。 OnPaintの件、ありがとうございます。 貴重なお時間ありがとうございました。 System.OutOfMemoryException はハンドルされませんでした。 Message="メモリが不足しています。" Source="System.Drawing" StackTrace: 場所 System.Drawing.TextureBrush..ctor(Image image, WrapMode wrapMode) 場所 System.Windows.Forms.ControlPaint.DrawBackgroundImage(Graphics g, Image backgroundImage, Color backColor, ImageLayout backgroundImageLayout, Rectangle bounds, Rectangle clipRect, Point scrollOffset, RightToLeft rightToLeft) 場所 System.Windows.Forms.Control.PaintBackground(PaintEventArgs e, Rectangle rectangle, Color backColor, Point scrollOffset) 場所 System.Windows.Forms.Control.PaintBackground(PaintEventArgs e, Rectangle rectangle) 場所 System.Windows.Forms.Control.OnPaintBackground(PaintEventArgs pevent) 場所 System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer, Boolean disposeEventArgs) 場所 System.Windows.Forms.Control.WmPaint(Message& m) 場所 System.Windows.Forms.Control.WndProc(Message& m) 場所 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) 場所 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) 場所 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 場所 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) 場所 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData) 場所 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) 場所 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) 場所 System.Windows.Forms.Application.Run(Form mainForm) |
|
投稿日時: 2007-05-14 07:29
InnerExceptionは空なのかなぁ?
stack overflow ではなく、memory overflow なのが気になる。例外発生時のstack trace は、get アクセッサだけなのでしょうか。 _________________ |
|
投稿日時: 2007-05-15 10:37
Jittaさん
InnerExceptionはnullです。 ロジックはシンプルに切り出してみたので、getアクセッサのみだと思います。 setアクセッサにもブレークをかけて見ましたがこちらには飛んでないようです。 HashTableを使わないで、通常のImageで内部変数をもち、BackgroundImageをオーバーライドしてこのImageで処理してみるとこのような現象はおこりません。 Apprication.Runで例外でブレークしますので、描画段階での処理で起きているようです。 かつて、Fontをアンビエントプロパティと気づかすにオーバーライドしたときに酷似した現象がおきたので、BackgroundImageもそうなのかと思い調べましたが、アンビエントプロパティではなかったです。。。確かにStack overflowではないですね。 漠然とですが (1)Collection系がだめなのか。ArrayListにしてみてトライする (2)ダブルバッファ あたりから調べてみます。 |
|
投稿日時: 2007-05-15 13:01
Jitta様、囚人様
すみません。解決いたしました。 ちなみにHashTableが問題ではなく、単純に内部変数でImageの変数をとって表示させようとしても現象が発生していました。先ほどの報告に間違いがありました。申し訳ありません。 検索中に以下の記事を見ていて気づきました。 http://www.atmarkit.co.jp/fdotnet/dotnettips/194nopaintbg/nopaintbg.html OutOfMemoryについては、解せないありますが、OnPaintの前にOnPaintBackgroundが呼ばれているのは確かのようで カスタムコントロールに protected override void OnPaintBackground(PaintEventArgs pevent) { // 何もしない // base.OnPaintBackground(pevent); } を追加することで、OutOfMemoryの現象は回避されています。 この記事以前に読んでいたのですが、見落としていました。 色々指針をいただき解決することができました。 ありがとうございます。 |
|
投稿日時: 2007-05-16 06:22
Bitmap のコンストラクタを、Stream を渡すもの以外に変えても解決するような気もする。
何となく、参照じゃなくてディープ コピーになっているように思う。 理由は、stream を確保し続けるところ。 stream が参照コピーできず、byte 配列にコピーし直してイメージを作り直しているんじゃないかなぁ?なもんだから、OutOfMemory になる、と。 繰り返すけど、気がするだけ。 ちげー。スタックに出てないやん。 失礼しました。 囚人さんの、再現できなかったというコードを公開して欲しいところ。おそらく、イメージは取り込んでしまってから Bitmap を作るようにコーディングしてあると思う。 [ メッセージ編集済み 編集者: Jitta 編集日時 2007-05-16 06:52 ] |