1

我一直在我正在处理的几个程序中进行线程化工作,并且我一直对某些东西到底在做什么感到好奇。

以下面的代码为例,它从一个线程运行以更新 UI:

Public Sub UpdateGrid() 
    If Me.InvokeRequired Then 
        Me.Invoke(New MethodInvoker(AddressOf UpdateGrid)) 
    Else 
        DataGridView1.DataSource = dtResults 
        DataGridView1.Refresh() 
        btnRun.Text = "Run Query" 
        btnRun.ForeColor = Color.Black 
    End If 
End Sub

Me.InvokeRequired 到底检查了什么,Me.Invoke 到底在做什么?我知道它以某种方式让我可以访问 UI 上的项目,但它是如何实现的呢?

顺便说一句,假设 UpdateGrid() 是一个返回值并具有必需参数的函数。调用 Me.Invoke 方法后如何传递参数以及如何获取返回值?我在没有参数的情况下尝试了这个,但没有返回任何东西,我不知道在调用时如何附加参数。

4

3 回答 3

3

Me.InvokeRequired正在检查它是否在 UI 线程上,如果不是TrueMe.Invoke则要求委托来处理差异线程之间的通信。

至于你的旁注。我通常使用一个事件来传递数据——这个事件仍然在 diff 线程上,但像上面一样,你可以委派工作。

Public Sub UpdateGrid() 
    'why ask if I know it on a diff thread
    Me.Invoke(Sub() 'lambda sub
               DataGridView1.DataSource = dtResults 
               DataGridView1.Refresh() 
               btnRun.Text = "Run Query" 
               btnRun.ForeColor = Color.Black 
              End Sub)
End Sub
于 2013-09-06T17:29:17.350 回答
1

Invoke()确保调用的方法将在 UI 线程上调用。当您想在另一个线程(因此,不是 UI 线程)中进行 UI 调整时,这很有用。

InvokeRequired检查您是否需要使用该Invoke()方法。

于 2013-09-06T17:03:45.320 回答
1

从您发布的示例中,需要更新 UI 的部分是Invoke逻辑的一部分,而数据的检索可以在工作线程/后台线程上完成。

If Me.InvokeRequired Then

这会检查是否Invoke()有必要。

Me.Invoke(New MethodInvoker(AddressOf UpdateGrid)) 

这保证了此逻辑将在 UI 线程上运行,并且由于它正在处理与 UI(网格)的交互,因此如果您尝试在后台线程上运行它,它将无法正常工作。

于 2013-09-06T17:07:47.243 回答