私のプログラムはCRMです。私はRad Ribbon Barを使用していましたので、画像がたくさんあるボタン、RadGridView(画像を含む列)画像。これはmdiの親子プログラムです。Main()メソッドでSystem.Drawing例外が発生しました - C#
OutOfMemoryException occurred in System.Drawing.dll
は、私は特定の部分が、ノー成功にGC.Collect()
を試してみました:そう多くのケースで
MDI子をロードしたり、いくつかのグリッドでの作業中は、プログラムがハングし、私は、このエラーを与えるビュー。画像を設定するためのコードはありません!たとえば、ボタンの画像を設定するために、私はそのプロパティをVisual Studioで使用しました。私はビジュアルモードのプロパティパネルを使って、このように他のすべてのコントロールイメージを設定しました。
及びこれらの図面に関連するいくつかのデザイナーのコードです:
btnCustomerList.Image = global::MyApp.Properties.Resources.CustomerList32;
gridViewCommandColumn1.Image = global::MyApp.Properties.Resources.ViewShop32;
とエラーがアプリで作業しながら、後に来るとき、それはProgram.cs
にし、ラインApplication.Run(new MainForm());
に表示されます。
static void Main()
{
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", AppDomain.CurrentDomain.BaseDirectory + "\\Settings.config");
bool ok;
Mutex m = new Mutex(true, WindowsIdentity.GetCurrent().Name.ToString().Split('\\')[1] + "MyApp", out ok);
if (ok)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// The Error will cause HERE
Application.Run(new MainForm());
GC.KeepAlive(m);
}
else
Application.Exit();
}
MainForm
は、リボンバーを含むmdi親である。 これは完全なスタックトレースです:
at System.Drawing.Image.FromHbitmap(IntPtr hbitmap, IntPtr hpalette)
at System.Drawing.Image.FromHbitmap(IntPtr hbitmap)
at System.Drawing.Icon.ToBitmap()
at System.Windows.Forms.ThreadExceptionDialog..ctor(Exception t)
at System.Windows.Forms.Application.ThreadContext.OnThreadException(Exception t)
at System.Windows.Forms.Control.WndProcException(Exception e)
at System.Windows.Forms.Control.ControlNativeWindow.OnThreadException(Exception e)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at MyApp.Program.Main() in d:\\MyApp\\Application\\MyApp\\Program.cs:line 36"
UPADTED:
リボンバーのボタンをクリックしてmdi-children
を呼び出すためのコードはここにある:
private void btnCustomerList_Click(object sender, EventArgs e)
{
OpenForm(new FormCustomerList(), "Customer List");
}
private void btnCustomerRelated_Click(object sender, EventArgs e)
{
OpenForm(new FormCustomerRelated(), "Customer Related");
}
ここではOpenForm
方法であり、
private void OpenForm(Form formType, string Caption)
{
foreach (Form nform in Application.OpenForms)
{
if (nform.GetType() == formType.GetType())
{
nform.Activate();
return;
}
}
this.MdiChildren.OfType<Form>().ToList().ForEach(x => x.Dispose());
GC.Collect();
Form form = formType;
form.MdiParent = this;
form.Dock = DockStyle.Fill;
form.Show();
this.Text = Caption;
}
およびすべてのmdi子供のフォームコンストラクタ、InitializeComponent();
の後にもGC.Collect();
を書きました。しかし、コメントに記載されているように、10000
オブジェクトまでタスクマネージャのGDI objects
が増えて増加し、アプリケーションがクラッシュします。
UPADTED:MOST ISSUE
私が最もGDI objects
の原因となる部分を発見したようです。どのフォームでも、テキストボックス、ドロップダウンリストなどのコントロールがいくつかあります。例えば、ユーザーがテキストボックスを入力した場合、その背後の色は黄色でなければなりません。だから私はすべてのコントロールを理解し、ターゲットを見つけて、定義されたルールでイベントを入力したり離したりするなど、フォームロードで呼び出すメインメソッドがあります。
private void FormCustomerList_Load(object sender, EventArgs e)
{
ClassCRMControls.AddEventHandler(this);
}
とClassCRMControls
クラス内部:このような何か
public static void AddEventHandler(Control parent)
{
foreach (Control c in parent.Controls)
{
if (c.GetType() == typeof(RadTextBox))
{
c.Enter += new EventHandler(ClassCRMControls.EnterEvent);
c.Leave += new EventHandler(ClassCRMControls.LeaveEvent);
}
else
AddEventHandler(c);
}
}
private static void EnterEvent(object sender, EventArgs e)
{
(sender as RadTextBox).TextBoxElement.TextBoxItem.BackColor = Color.FromArgb(255, 251, 147);
}
private static void LeaveEvent(object sender, EventArgs e)
{
(sender as RadTextBox).TextBoxElement.TextBoxItem.ResetValue(LightVisualElement.BackColorProperty, ValueResetFlags.Local);
}
ログの完全なスタックトレースは、多分それはいくつかの手がかりを提供します。 – Evk
Hmya、プログラムに不正なハンドルリークがあります。それは非常に悪いので、例外ダイアログでさえもはや表示することはできません。タスクマネージャの[プロセス]タブに表示されるものです。あなたはそれが着実に増加し、それは10000誰もがこれらの画像を配置しないためのあらゆる賞を獲得しないが、それは致命的ではありません到達したときにショーが終わって参照してくださいよ、GDIオブジェクトの列を追加します。すでにGC.Collect()を試してみたと言いますが、ファイナライザのスレッドがデッドロックしている可能性があります。アンマネージデバッグを有効にし、それが何をしているのかを調べます。 USER()はControls.Clearを使用することによって生じたWinformsの中の別の伝統的なバグがそれらをされて漏れて、列オブジェクト()または削除で –
も見えます。 –