Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 无法在窗体关闭时访问已释放的对象_Vb.net_Exception_Exception Handling - Fatal编程技术网

Vb.net 无法在窗体关闭时访问已释放的对象

Vb.net 无法在窗体关闭时访问已释放的对象,vb.net,exception,exception-handling,Vb.net,Exception,Exception Handling,我试图为一个有网格和滴答计数器的游戏编写一些代码,但是网格只是尝试填充窗口,而不是停止,并且不显示滴答计数器。不断出现的错误是: System.Windows.Forms.dll中首次出现类型为“System.ObjectDisposedException”的异常 我不知道这意味着什么,也不知道如何修复它 这是我的密码: Public Class Form1 Dim G As Graphics Dim BBG As Graphics Dim BB As Bitmap

我试图为一个有网格和滴答计数器的游戏编写一些代码,但是网格只是尝试填充窗口,而不是停止,并且不显示滴答计数器。不断出现的错误是:

System.Windows.Forms.dll中首次出现类型为“System.ObjectDisposedException”的异常

我不知道这意味着什么,也不知道如何修复它

这是我的密码:

Public Class Form1
    Dim G As Graphics
    Dim BBG As Graphics
    Dim BB As Bitmap
    Dim r As Rectangle

    Dim tSec As Integer = TimeOfDay.Second
    Dim tTicks As Integer = 0
    Dim MaxTicks As Integer = 0

    Dim IsRunning As Boolean = True

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.Show()
        Me.Focus()

        G = Me.CreateGraphics
        BB = New Bitmap(Me.Width, Me.Height)

        StartGameLoop()
    End Sub

    Private Sub DrawGraphics()
        For X = 0 To 19
            For Y = 0 To 14
                r = New Rectangle(X * 32, Y * 32, 32, 32)

                G.FillRectangle(Brushes.BurlyWood, r)
                G.DrawRectangle(Pens.Black, r)
            Next
        Next
        G.DrawString("Ticks: " & tTicks & vbCrLf & _
                    "TPS: " & MaxTicks, Me.Font, Brushes.Black, 650, 0)

        G = Graphics.FromImage(BB)

        BBG = Me.CreateGraphics
        BBG.DrawImage(BB, 0, 0, Me.Width, Me.Height)

        G.Clear(Color.Wheat)
    End Sub

    Private Sub StartGameLoop()
        Do While IsRunning = True
            Application.DoEvents()



            DrawGraphics()

            TickCounter()
        Loop
    End Sub

    Private Sub TickCounter()
        If tSec = TimeOfDay.Second And IsRunning = True Then
            tTicks = tTicks + 1
        Else
            MaxTicks = tTicks
            tTicks = 0
            tSec = TimeOfDay.Second
        End If
    End Sub
End Class

你在这里利用了很多坏习惯

首先,使用
Me.CreateGraphics()
很糟糕,结果对象只能绘制一次,这意味着您必须多次调用它。不断调用它只会创建越来越多的图形对象,从而增加内存使用。即使每次完成绘制后都要处理它们,这仍然是一个巨大的瓶颈,因为它会减慢处理速度

其次,使用
Application.DoEvents()
是一种非常糟糕的做法,它会像那样在循环中消耗CPU。除非正确使用(您不这样做),否则可能会导致意外和不可预测的行为。你所犯的错误就是这种意外行为的一个很好的例子

我建议您阅读这篇MSDN博客,它准确地解释了为什么一个人不应该使用
Application.DoEvents()


相反,为了正确执行此操作:

  • 用表单替换
    Me.CreateGraphics()
    ,并通过
    e.Graphics
    对象在其中绘制所有图形

  • 将您的游戏循环替换为连续调用重新绘制表单的循环

例如:

Dim WithEvents GameTimer As New Timer() With {.Interval = 1}

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    GameTimer.Start()
End Sub

Private GameTimer_Tick(sender As System.Object, e As System.EventArgs) Handles GameTimer.Tick
    Me.Invalidate() 'Redraw the form.
    TickCounter()
End Sub

Private Sub Form1_Paint(sender As System.Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    e.Graphics.Clear(Color.Wheat)

    For X = 0 To 19
        For Y = 0 To 14
            Dim r As New Rectangle(X * 32, Y * 32, 32, 32)

            e.Graphics.FillRectangle(Brushes.BurlyWood, r)
            e.Graphics.DrawRectangle(Pens.Black, r)
        Next
    Next

    e.Graphics.DrawString("Ticks: " & tTicks & vbCrLf & _
                          "TPS: " & MaxTicks, Me.Font, Brushes.Black, 650, 0)
End Sub

你能试试我给你的窍门吗?也许能帮你找到你的问题