16

「GDI+ で一般的なエラーが発生しました」という例外が発生するのはなぜですか?

IntPtr hicon = tempBitmap.GetHicon();             
Icon bitmapIcon = Icon.FromHandle(hicon);            
return bitmapIcon;

アプリケーションが 30 分以上実行されているときにエラーが発生しました。(私は毎秒に変換System.Drawing.Bitmapしています)System.Drawing.Icon

ここに画像の説明を入力

4

2 に答える 2

29

ハンドルリークが原因です。TaskMgr.exe の [プロセス] タブでリークを診断できます。表示 + 列を選択し、ハンドル、GDI オブジェクト、およびユーザー オブジェクトを選択します。プログラムの実行中にこれらの列を観察してください。私の推測が正しければ、プロセスの GDI オブジェクトの値が着実に上昇していることがわかります。10,000 に達するとショーは終了し、Windows はそれ以上のオブジェクトのリークを許可しません。

Icon.FromHandle の備考セクションには、次のように記載されています。

このメソッドを使用する場合は、Win32 API の DestroyIcon メソッドを使用して結果のアイコンを破棄し、リソースが確実に解放されるようにする必要があります。

これは良いアドバイスですが、通常はかなり面倒です。この回答では、Icon オブジェクトがハンドルを所有し、自動的に解放するように強制するハックを見つけることができます。関連するコードは、「プライベート アイコン コンストラクターの呼び出し」セクションの後にあります。

于 2012-08-19T13:25:40.930 に答える
6

You probably need to clean up your icon.

The example for Icon.FromHandle on MSDN shows you how. Unfortunately it requires PInvoke:

[System.Runtime.InteropServices.DllImport("user32.dll", CharSet=CharSet.Auto)]
extern static bool DestroyIcon(IntPtr handle);

And then inside your method:

IntPtr hicon = tempBitmap.GetHicon();             
Icon bitmapIcon = Icon.FromHandle(hicon);        

// And then somewhere later...
DestroyIcon(bitMapIcon.Handle);    

If you call DestoryIcon before you use it, it may not work. For my own particular instance of this problem, I ended up keeping a reference to the last icon I created and then called DestroyIcon on it the next time I generated an icon.

于 2014-04-23T23:01:06.677 に答える