制作洪水填充动画 vb return object is currently used elsewhere using thread.sleep

Making animation of flood fill in vb return object is currently used elsewhere using thread.sleep

我尝试在 vb 中使用睡眠制作动画洪水填充(扫描线算法)。所以它会显示像素被着色的顺序。它会工作一点点,但随后会 return object is currently used elshere

这是我的代码

Sub AnimatedRFRecursive(ByVal P As Point, ByVal C0 As Color, ByVal C1 As Color)

    Dim i, xL, xR As Integer
    Dim a As Point
    i = P.X
    While (i >= 0 AndAlso BMP.GetPixel(i, P.Y) = C0)
        Thread.Sleep(10)
        BMP.SetPixel(i, P.Y, C1)
        PictureBox1.Invoke(New Action(Sub() PictureBox1.Image = BMP))
        i -= 1
    End While
    xL = i + 1
    i = P.X + 1
    While (i < 500 AndAlso BMP.GetPixel(i, P.Y) = C0)
        Thread.Sleep(10)
        BMP.SetPixel(i, P.Y, C1)
        PictureBox1.Invoke(New Action(Sub() PictureBox1.Image = BMP))
    End While
    xR = i - 1
    For i = xL To xR
        If (P.Y < 349 AndAlso BMP.GetPixel(i, P.Y + 1) = C0) Then
            a.X = i
            a.Y = P.Y + 1

            AnimatedRFRecursive(a, C0, C1)
        End If
        If (P.Y > 0 AndAlso BMP.GetPixel(i, P.Y - 1) = C0) Then
            a.X = i
            a.Y = P.Y - 1
            AnimatedRFRecursive(a, C0, C1)
        End If
    Next
End Sub

我是这样称呼它的

Dim thr As New Threading.Thread(Sub() AnimatedRFRecursive(point, C, Color))
thr.Start()

请告诉我我哪里做错了,或者如果你有任何其他有效的方法也可以。谢谢

您有多个线程需要访问同一个对象 (BMP)。这将要求您同步对 BMP 对象的访问。

请注意,您的原始代码有两个幻数(500 和 349),我假设它们对应于位图的宽度和高度。如果此假设不正确,请更改以下代码中变量的用法。

Private BMP As Bitmap
Private BMPKey As New Object
Private Sub UpdatePictureBox()
    PictureBox1.Invoke(Sub()
                                SyncLock BMPKey
                                    Dim oldBM As Image = PictureBox1.Image
                                    PictureBox1.Image = New Bitmap(BMP)
                                    If oldBM IsNot Nothing Then oldBM.Dispose()
                                End SyncLock

                                End Sub)

End Sub

Private Function GetBMPPixel(x As Int32, y As Int32) As Color
    SyncLock BMPKey
        Return BMP.GetPixel(x, y)
    End SyncLock
End Function

Private Sub SetBMPPixel(x As Int32, y As Int32, c As Color)
    SyncLock BMPKey
        BMP.SetPixel(x, y, c)
    End SyncLock
End Sub

Sub AnimatedRFRecursive(ByVal P As Point, ByVal C0 As Color, ByVal C1 As Color)

     Dim i, xL, xR As Integer
     Dim a As Point
     i = P.X
     Dim width As Int32
     Dim height As Int32
     SyncLock BMPKey
        width = BMP.Width       ' original code magic number of 500 
        height = BMP.Height ' original code magic number of 349  
     End SyncLock
     While (i >= 0 AndAlso GetBMPPixel(i, P.Y).ToArgb = C0.ToArgb)
          Thread.Sleep(10)
          SetBMPPixel(i, P.Y, C1)
          UpdatePictureBox()
          i -= 1
     End While
     xL = i + 1
     i = P.X + 1
     While (i < width - 1 AndAlso GetBMPPixel(i, P.Y).ToArgb = C0.ToArgb)
          Thread.Sleep(10)
          SetBMPPixel(i, P.Y, C1)
          UpdatePictureBox()
     End While
     xR = i - 1
     For i = xL To xR
          If (P.Y < height - 1 AndAlso GetBMPPixel(i, P.Y + 1).ToArgb = C0.ToArgb) Then
                a.X = i
                a.Y = P.Y + 1

                AnimatedRFRecursive(a, C0, C1)
          End If
          If (P.Y > 0 AndAlso GetBMPPixel(i, P.Y - 1).ToArgb = C0.ToArgb) Then
                a.X = i
                a.Y = P.Y - 1
                AnimatedRFRecursive(a, C0, C1)
          End If
     Next
End Sub