'的System.OutOfMemoryException' :创建窗口句柄时出错

时间:2017-04-27 12:16:47

标签: c# winforms out-of-memory dispose

我正在编写一个中等winforms应用程序......不时地创建某些表单我会得到这个例外。

我过去曾解决过这个问题,但没有对正在发生的事情进行适当的了解......

令人费解的是,昨天当我完成这个表格并对其进行测试时,一切正常,现在我明白了:

  

未处理的类型' System.OutOfMemoryException'发生了   在System.Windows.Forms.dll

中      

其他信息:创建窗口句柄时出错。

此代码块中抛出异常:

    public partial class PonovniIspisRacunaForm : Form
        {    

        DataTable dnevniPrometTable;
        DataTable kontrolnaTrakaTable;
        DataTable ukupniDnevniPrometTable;
        DataTable stavkeRacunaTable;
        ZisCode.Hibernate.Mdb.DataModel dnevniPrometDataModel;
        ZisCode.Hibernate.Mdb.DataModel kontrolnaTrakaDataModel;
        OsnovniPodaci.Porezi.Stope stope;
        string brojRacuna;
        string ZKI;
        string JIR;
        string Operator;
        //decimal ukupno = 0.00m;

        decimal tarifa;
        decimal kolicina;
        decimal iznos;
        decimal porez;
        decimal porez25;
        decimal porez05;
        decimal porez13;
        decimal povratnaUkupno;
        decimal osnov25;
        decimal osnov05;
        decimal osnov13;
        //decimal nabavna; 

        PrintDocument printDocument;

        public PonovniIspisRacunaForm()
        {
            InitializeComponent();
        }

    private void FinancijskiRekapitular_Load(object sender, EventArgs e)
            {
                stope = new OsnovniPodaci.Porezi.Stope();

                // popunjava današnji datum
                this.dtpDatum.Value = DateTime.Today;

                // Get Data Table za određeni datum:
                dnevniPrometDataModel = ZisCode.DataModels.Get("DnevniPromet");
                kontrolnaTrakaDataModel = ZisCode.DataModels.Get("KontrolnaTraka");

                PrintSetup();

                ukupniDnevniPrometTable = MergeDnevniKontrolna();
                if (ukupniDnevniPrometTable.Rows.Count != 0)
                {
                    FillComboBox();
            }
        }
    private void FillComboBox()
            {
                cbBrojRacuna.DataSource = ZisCode.Methods.DataTableOperations.SortDataTable(ukupniDnevniPrometTable, "Dokument", "DESC") // orderbydescending
                    .AsEnumerable().GroupBy(row => row.Field<string>("Dokument")).Select(group => group.First()).CopyToDataTable(); // groupby brojRacuna-Dokument
                cbBrojRacuna.DisplayMember = "Dokument"; // Broj Računa
                cbBrojRacuna.ValueMember = "Dokument";
                cbBrojRacuna.SelectedIndex = 0;
            }

            private void PrintSetup()
            {
                // priprema za ispis
                printDocument = new PrintDocument();
                printDocument.DefaultPageSettings.PaperSize = new PaperSize("Racun size", 295, 500);
                printDocument.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(CreateRekapitular);
                // uklanja poruku dialog box (printing ..) kod ispisa
                PrintController printController = new StandardPrintController();
                printDocument.PrintController = printController;
                // popravlja font
                printPreview.UseAntiAlias = true;
            }
}

更具体这一行:this.dtpDatum.Value = DateTime.Today; 为什么??我不知道......

我尝试在构造函数中设置dateTimePicker,并且得到了与窗口句柄无关的不同异常。

我已经在其他问题上阅读了这个案例,但没有真正点击过我。

Winforms issue - Error creating window handle

Error Creating Window Handle

这两个答案对我没有帮助,因为答案是模棱两可的,并希望我知道处理首先应该如何处理。帮助,我是一个n00b!

更新已经发布了几乎所有类的代码

3 个答案:

答案 0 :(得分:4)

窗口句柄是非托管资源。只有这么多。如果你不释放这些句柄,Windows就会用完,你将获得例外。

使用原生HANDLE的类需要在不再需要它们时释放它们。这些类将实现IDisposable。您应该研究一下,它是.NET的核心部分,对于处理非托管资源(如句柄)至关重要。

启用静态代码分析(右键点击Project - &gt; Properties - &gt; Code Analysis,然后选择Enable on build并选择Microsoft all rules)和修复所有违规行为,尤其是那些未处置的IDisposable

答案 1 :(得分:1)

由于您的异常是OutOfMemory,因此您可能只是内存不足。检查任务管理器,看看你有多少可用的内存,我建议你通过像RedGate这样的内存分析器运行你的应用程序或类似的东西来查看泄漏的位置。如果处置,请查看此asnwer以获取更多信息C# Form.Close vs Form.Dispose

答案 2 :(得分:0)

问题是私人无效

dtpDatum_TextChanged(object sender, EventArgs e)
{
    ukupniDnevniPrometTable = MergeDnevniKontrolna();
    FillComboBox();
}

我猜这个事件被激发太多次并导致内存泄漏