【问题标题】:'System.OutOfMemoryException' : Error creating window handle“System.OutOfMemoryException”:创建窗口句柄时出错
【发布时间】:2017-09-25 05:40:51
【问题描述】:

我正在编写一个中等大小的 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

这两个答案对我没有帮助,因为答案模棱两可,并希望我首先知道 dispose 应该如何工作。救命,我是n00b!

更新按照我的要求发布了几乎所有类的代码

【问题讨论】:

  • 你能为 PrintSetup 和 FillComboBox() 添加一些代码吗?你有一些通用变量吗?在关闭表单时你会做什么?
  • @WaiFungAuYeung 是的,我确实有一堆变量,并且在关闭表单时我不处理大声笑我应该怎么做?即使加载表单时抛出此异常
  • 我用更多代码更新了问题

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


【解决方案1】:

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

【讨论】:

  • 我不认为这是问题所在,可能是 dateTimePicker 没有处理(?!)因为它是一个自定义用户控件...我不确定我只是在这里猜测 voer 因为 dtp是异常的来源
【解决方案2】:

窗口句柄是非托管资源。他们只有这么多。如果您不释放这些句柄,Windows 将耗尽,您将获得异常。

使用本机 HANDLEs 的类将需要在不再需要它们时释放它们。这些类将实现IDisposable。您应该对此进行研究,它是 .NET 的核心部分,对于使用句柄等非托管资源至关重要。

打开您的静态代码分析(右键单击Project -> Properties -> Code Analysis 并选择Enable on build 并选择Microsoft all rules)并修复所有违规行为,尤其是那些未处置的IDisposable秒。

【讨论】:

  • nvoigt 感谢您的回复,我什至不知道这个选项存在 - 现在我觉得自己像个大 n00b...
【解决方案3】:

问题是私有无效

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

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

【讨论】:

    猜你喜欢
    • 2011-10-17
    • 1970-01-01
    • 2013-01-30
    • 2013-06-02
    • 1970-01-01
    • 2016-09-01
    • 2013-12-10
    相关资源
    最近更新 更多