创建窗口句柄时出错。控件处理不当会导致内存堆积和崩溃

时间:2019-03-26 16:59:31

标签: vb.net

我有一个应用程序,每30秒刷新一次数据。在主页上,为每个数据项添加了一个动态控件。触发计时器后,控件将被处理,不设置任何内容,并清除选项卡页面。

问题在于它们不丢弃,每次刷新都会不断增加私密性。大约70mb的专用字节,应用程序崩溃,并出现Message = Error创建窗口句柄。 NativeErrorCode = 1158。可以是获取错误的表单上的任何控件。

使用System.GC.Collect()进行了尝试,覆盖了对控件的Dispose以及我发现的与此问题相关的许多其他技术。

我认为“处置”或“垃圾收集”实际上并没有工作。这是清除控件的子项。

修改后的代码(简体):

Sub ClearHotLists()
    For i As Int16 = ControlCollection.Count - 1 To 0 Step -1
        ControlCollection(i).Dispose()
    Next
End Sub

Private Sub TimerHotList_Tick(sender As Object, e As EventArgs) Handles TimerHotList.Tick
    PopulateHotList(False)
End Sub

Sub PopulateHotList(Connect)

    ClearHotLists()

    ControlCollection.Clear()

    Dim hpos As Int16 = 10
    Dim vpos As Int16 = 10

    If Connect Then sqlConn.Open()

    sqlConn3.Open()

    Select Case Me.tcMain.SelectedIndex

        Case 0
            AddHotListItems("Ground", hpos, vpos, Me.tabShipping)
            vpos += 230 : hpos = 10
            AddHotListItems("Hand Carry", hpos, vpos, Me.tabShipping)
            vpos += 230 : hpos = 10
            AddHotListItems("Red", hpos, vpos, Me.tabShipping)
            vpos += 230 : hpos = 10
            AddHotListItems("Outside Vendor", hpos, vpos, Me.tabShipping)
        Case 1
            hpos = 10 : vpos = 10
            For i As Int16 = 0 To InspCnt - 1
                AddHotListItems(InspArr(i), hpos, vpos, Me.tabInspection)
                vpos += 230 : hpos = 10
            Next
        Case 2
            hpos = 10 : vpos = 10
            For i As Int16 = 0 To DebCnt - 1
                AddHotListItems(DebArr(i), hpos, vpos, Me.tabDeburring)
                vpos += 230 : hpos = 10
            Next

    End Select

    sqlConn3.Close()

    If Connect Then sqlConn.Close()

End Sub

Sub AddHotListItems(ByVal ItemType As String, ByRef hpos As Int16, ByRef vpos As Int16, ByVal Tab As TabPage)

        Dim DynHotListItem As HotListItem
        Dim ControlObject As Control
        sql = "SELECT * FROM tWhiteBoardHotList WHERE Type='" & ItemType & "' ORDER BY PartNumber"
        sqlComm = New OdbcCommand(sql, sqlConn)
        r = sqlComm.ExecuteReader
        While r.Read
            ControlObject = New HotListItem
            ControlObject.Location = New System.Drawing.Point(vpos, hpos + DynLabel.Height)
            Tab.Controls.Add(ControlObject)
            DynHotListItem = ControlObject
            DynHotListItem.lblPartNumber.Text = r!PartNumber

            'BUNCH OF CODE HERE TO FILL THE CONTROLS ON HotListItem

            ControlCollection.Add(DynHotListItem)

        End While
        r.Close()

End Sub

原始代码:         子ClearHotLists()

    Dim DynHotListItem As HotListItem
    Dim DynLabel As Label

    For Each DynTabPage As TabPage In Me.tcMain.Controls
        If DynTabPage.Name = "tabShipping" Or DynTabPage.Name = "tabInspection" Or DynTabPage.Name = "tabDeburring" Then
            For Each ctr As Control In DynTabPage.Controls
                If TypeOf ctr Is HotListItem Then
                    DynHotListItem = ctr
                    DynHotListItem.Dispose()
                    DynHotListItem = Nothing
                    DynTabPage.Controls.Remove(DynHotListItem)
                    ctr.Dispose()
                Else
                    DynLabel = ctr
                    DynLabel.Dispose()
                    DynLabel = Nothing
                    DynTabPage.Controls.Remove(DynLabel)
                    ctr.Dispose()
                End If
            Next
            DynTabPage.Controls.Clear()
        End If
    Next

    System.GC.Collect(GCCollectionMode.Forced)
    System.GC.Collect(0, GCCollectionMode.Forced)
    System.GC.Collect(1, GCCollectionMode.Forced)
    System.GC.Collect(2, GCCollectionMode.Forced)

End Sub

期望的结果是控件将被处置,并避免由于内存泄漏而导致崩溃。

0 个答案:

没有答案