Метод BeginInvoke используется для асинхронного вызова делегата метода в потоке, который создал дескриптор элемента управления.Поток пользовательского интерфейса здесь.Его подпись:
Public Function BeginInvoke (method As Delegate) As IAsyncResult
Затем делегат method
объявляется в том же потоке, где был создан вызываемый элемент управления.
Затем делегат должен быть объявлен следующим образом:
В потоке пользовательского интерфейса:
Delegate Sub MyUpdateDelegate()
Public Sub MyUpdateMethod()
[SomeControl].Text = "Updated Text"
End Sub
В другом потоке:
Private Sub InvokeFromAnotherThread()
'(...)
[SomeControl].BeginInvoke(New MyUpdateDelegate(AddressOf MyUpdateMethod))
'Or
Me.BeginInvoke(New MyUpdateDelegate(AddressOf MyUpdateMethod))
'(...)
End Sub
Использование анонимного метода на месте не обрезает его.
Существует ярлык, предоставленный делегатом MethodInvoker :
MethodInvoker предоставляет простой делегат, который используется для вызова метода со списком параметров void.Этот делегат может использоваться при вызове метода Invoke элемента управления или когда вам нужен простой делегат, но вы не хотите определять его самостоятельно.
Используя делегат MethodInvoker
, нет необходимостиобъявить делегата в потоке пользовательского интерфейса.Здесь можно использовать анонимный метод, он будет вызываться в потоке пользовательского интерфейса:
Private Sub InvokeFromAnotherThread()
'(...)
BeginInvoke(New MethodInvoker(Sub() [SomeControl].Text = "Updated Text"))
'(...)
End Sub
или:
Private Sub InvokeFromAnotherThread()
'(...)
BeginInvoke(New MethodInvoker(
Sub()
[SomeControl].Text = "Updated Text"
[SomeOtherControl].BackColor = Color.Red
End Sub))
'(...)
End Sub
Почему я предложил таймер:
В используемом вами потоке есть только одна задача: обновить элемент управления в потоке пользовательского интерфейса, а затем перевести в спящий режим.
Для выполнения этой задачи необходимо вызвать метод в потоке пользовательского интерфейса.Если причина, по которой поток был создан, состоит в том, чтобы избежать блокировки потока пользовательского интерфейса, таймер будет делать то же самое.В частности, System.Windows.Forms.Timer
вызовет событие Tick
в потоке пользовательского интерфейса без вызовов между потоками.Практический эффект более или менее одинаков.