Chương trình của tôi là CRM, tôi sử dụng Rad Ribbon Bar, nhiều nút với hình ảnh, RadGridView (một số cột chứa hình ảnh) và rất nhiều điều khiển khác chứa hình ảnh. Đó là một chương trình mẹ/con mdi.System.Drawing Out of Memory Exception On Main() Phương thức - C#
Trong rất nhiều trường hợp khi tải một đứa trẻ MDI hoặc làm việc với một số lưới xem chương trình sẽ treo và đưa cho tôi lỗi này:
OutOfMemoryException occurred in System.Drawing.dll
tôi đã cố gắng GC.Collect()
trên các bộ phận nhất định, nhưng không thành công . Để thiết lập hình ảnh không có mã! ví dụ để thiết lập một hình ảnh cho một nút, tôi đã sử dụng các thuộc tính của nó trong studio trực quan. Tôi đã đặt Tất cả các hình ảnh điều khiển khác theo cách này bằng cách sử dụng bảng thuộc tính ở chế độ trực quan.
và đây là một số mã thiết kế liên quan đến bản vẽ:
btnCustomerList.Image = global::MyApp.Properties.Resources.CustomerList32;
gridViewCommandColumn1.Image = global::MyApp.Properties.Resources.ViewShop32;
và Khi Các lỗi được đưa ra sau một thời gian làm việc với các ứng dụng, nó sẽ xuất hiện trong Program.cs
và trong dòng 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
là cha mẹ mdi có chứa thanh Ribbon. và đây là Full stack trace:
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:
mã để gọi mdi-children
bằng cách nhấp vào nút thanh ribbon là ở đây:
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");
}
và đây là OpenForm
phương pháp:
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;
}
và trong mọi mdi nhà xây dựng biểu mẫu của trẻ em, sau InitializeComponent();
Tôi cũng đã viết GC.Collect();
. Nhưng như đã nói trong phần nhận xét, GDI objects
trong trình quản lý tác vụ sẽ tăng và tăng cho đến 10000
đối tượng và sau đó ứng dụng sẽ gặp sự cố.
UPADTED: Vấn đề MOST
Có vẻ như tôi đã tìm thấy phần gây nhất GDI objects
. Trong mọi hình thức có một số điều khiển như hộp văn bản, danh sách thả xuống vv. Tôi đã thiết lập một số quy tắc cho họ, ví dụ nếu người dùng nhập vào một hộp văn bản, màu sắc của nó phải là màu vàng và sau khi rời khỏi nó phải là màu trắng một lần nữa. Vì vậy, có một phương pháp chính mà tôi gọi trong tải hình thức để biết chữ thông qua tất cả các điều khiển và tìm thấy những mục tiêu và thêm ví dụ nhập và để lại các sự kiện với các quy tắc được xác định. một cái gì đó như thế này:
private void FormCustomerList_Load(object sender, EventArgs e)
{
ClassCRMControls.AddEventHandler(this);
}
và bên ClassCRMControls
lớp:
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);
}
Ghi nhật ký ngăn xếp đầy đủ của ngoại lệ này, có thể nó sẽ cung cấp một số đầu mối. – Evk
Hmya, chương trình có một rò rỉ xử lý xấu. Nó là xấu như vậy mà ngay cả hộp thoại ngoại lệ không thể được hiển thị nữa. Đó là điều bạn có thể thấy trong Task Manager, tab Processes. Thêm cột cho các đối tượng GDI, bạn sẽ thấy nó tăng dần và chương trình kết thúc khi đạt đến 10000. Không ai giành được bất kỳ giải thưởng nào để không xử lý những hình ảnh này, nhưng nó không gây tử vong. Bạn đã nói rằng bạn đã thử GC.Collect(), nó không giúp đỡ sau đó thread finalizer có lẽ là bế tắc. Bật gỡ lỗi không được quản lý và tìm hiểu xem nó đang làm gì. –
Ngoài ra hãy nhìn vào cột USER Objects, rò rỉ đó là một lỗi truyền thống khác trong Winforms gây ra bằng cách sử dụng Controls.Clear() hoặc Remove(). –