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