Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.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 这个BeginInvoke(Sub())做什么?_Vb.net_Begininvoke - Fatal编程技术网

Vb.net 这个BeginInvoke(Sub())做什么?

Vb.net 这个BeginInvoke(Sub())做什么?,vb.net,begininvoke,Vb.net,Begininvoke,我遇到了以下代码: Public Sub fun_imageCallback(ByVal data As IntPtr, ByVal rows As Integer, ByVal cols As Integer, ByVal channels As Integer, ByVal timestamp As Long) 'Console.WriteLine(rows + " " + cols + " " + channels); imageMutex.Wa

我遇到了以下代码:

    Public Sub fun_imageCallback(ByVal data As IntPtr, ByVal rows As Integer, ByVal cols As Integer, ByVal channels As Integer, ByVal timestamp As Long)


        'Console.WriteLine(rows + " " + cols + " " + channels);
        imageMutex.WaitOne()
        If imageCamera IsNot Nothing Then
            imageCamera.Dispose()
        End If

        imageCamera = New Bitmap(cols, rows, channels * cols, PixelFormat.Format8bppIndexed, data)

        ' The default palette has strange colours, not grayscale
        Dim pal As ColorPalette = imageCamera.Palette
        For i As Integer = 0 To 255
            pal.Entries(i) = Color.FromArgb(i, i, i)
        Next
        imageCamera.Palette = pal
        imageMutex.ReleaseMutex()

        If Me.InvokeRequired Then

            Me.BeginInvoke(
        Sub()
            imageMutex.WaitOne()

            pbCamera.Image = DirectCast(imageCamera.Clone(), Bitmap)
            imageMutex.ReleaseMutex()
        End Sub
    )
        End If

    End Sub
我不明白以下四行是怎么做的:

    If Me.InvokeRequired Then

        Me.BeginInvoke(
    Sub()
        imageMutex.WaitOne()
怎么读呢

谢谢大家!

我建议你先读一些背景知识

invokererequired
属性的要点是确定当前是否在拥有指定控件的线程上执行<当在创建控件的线程上获取代码>InvokeRequired时,它是
False
,而在其他每个线程上获取
True
。一般来说,所有控件都是在同一个线程上创建的——应用程序启动的线程——这就是为什么它经常被称为UI线程的原因

如果在创建控件的线程上执行,则直接访问该控件的其他成员是安全的。如果您在不同的线程上,则需要在所属线程上调用方法调用,否则可能会发生不好的事情。
Invoke
BeginInvoke
方法在创建控件的线程上执行方法调用
Invoke
等待调用完成,而
BeginInvoke
立即返回,代码继续在当前线程上执行,而被调用的方法在UI线程上执行

在您的案例中,重要的部分是:

pbCamera.Image=DirectCast(imageCamera.Clone(),位图)
这就是访问
PictureBox
Image
属性,因此必须在UI线程上执行。代码测试表单的
invokererequired
属性,如果该属性为
False
,则表示当前代码未在UI线程上执行,因此直接访问该
图像
属性不安全。
BeginInvoke
方法将在UI线程上执行指定的Lambda表达式,从而可以安全地访问其中的
Image
属性

调用
Invoke
BeginInvoke
时,通过提供委托指定要执行的方法。委托是指方法的对象。可以使用
AddressOf
操作符创建常规命名方法的委托,在大多数情况下,这就是我在本答案开头链接的示例中所做的。Lambda表达式是为匿名方法创建委托的另一种方法。该代码类似于编写包含以下代码的命名方法:

imageMutex.WaitOne()
pbCamera.Image=DirectCast(imageCamera.Clone(),位图)
imageMutex.ReleaseMutex()文件
然后使用
AddressOf
为该方法创建一个委托。它的工作方式是
Invoke
BeginInvoke
方法在后台发挥魔力,将上下文切换到UI线程,然后在该线程上执行委托引用的方法

如果您不确定学员的工作方式或能力,您可能有兴趣了解他们是活动背后的魔力。事件基本上是代表的集合。考虑<代码>点击<代码>事件>代码>按钮<代码>。您在表单中编写了一个方法,希望在单击
按钮时执行该方法。
按钮如何执行该方法?注册事件处理程序实际上是创建引用该方法的委托,并将其添加到该事件的集合中。当
按钮
引发事件时,它基本上通过委托集合循环并调用每个委托