我一直在为我正在开展的一些项目中的线程工作做很多工作,而且我一直很好奇究竟是做了什么。
例如,以下代码从一个线程运行以更新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究竟在做什么?我知道它以某种方式让我可以访问用户界面上的项目,但它是如何实现这一目标的呢?
在旁注中,假设UpdateGrid()是一个返回值并具有必需参数的函数。我如何传递参数以及在调用Me.Invoke方法后如何获得返回值?我在没有参数的情况下尝试了这个但是“没有”被返回,我无法弄清楚在调用时如何附加参数。
答案 0 :(得分:2)
Me.InvokeRequired
正在检查它是否在UI线程上,如果不是等于True
,Me.Invoke
要求委托来处理差异线程之间的通信。
至于你的旁注。我通常使用一个事件来传递数据 - 这个事件仍然在差异线程上,但是像上面一样,你可以委派工作。
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
答案 1 :(得分:1)
Invoke()
确保将在UI线程上调用调用的方法。当您想在另一个线程中进行UI调整时,这非常有用(因此,不是UI线程)。
InvokeRequired
会检查您是否需要使用Invoke()
方法。
答案 2 :(得分:1)
从您发布的示例中,需要更新UI的部分是Invoke
逻辑的一部分,而数据的检索可以在工作/后台线程上完成。
If Me.InvokeRequired Then
这会检查是否需要Invoke()
。
Me.Invoke(New MethodInvoker(AddressOf UpdateGrid))
这保证了这个逻辑将在UI线程上运行,并且因为它正在处理与UI(网格)的交互,那么如果你试图在后台线程上运行它,它将无法工作。