我曾经是一名xcode程序员。
在创建应用程序时,我倾向于在其他线程上做大部分事情。
偶尔,例如当我想访问UI线程时,我会在主线程上做一些事情。
说我做了
//在网络上加载一些繁重的资源 doOnMainThread(sub()updateUIandStuff()) //继续做其他事情。
我如何在VB中实现doOnMainthread?
很久以前,在objective-c中有一种简单的方法可以做到这一点。如何在vb.net中这样做
答案 0 :(得分:2)
有两种常用方法可以实现这一目标; Delegates或调用lambda。以下示例将直接粘贴到新的WinForms项目中,并在设计器中添加了两个标签:
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim bw As New System.ComponentModel.BackgroundWorker
AddHandler bw.DoWork, AddressOf BackgroundWorker_DoWork
bw.RunWorkerAsync()
End Sub
Delegate Sub UpdateLabelDelegate(ByVal labelText As String)
Private Sub UpdateLabel(ByVal labelText As String)
Label2.Text = labelText
End Sub
Private Sub BackgroundWorker_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs)
For i As Integer = 1 To 10000
Dim testText As String = "Loop#" & i.ToString
'You can easily check your thread's access to the UI using:
' WinForms "If InvokeRequired Then : End If"
' WPF "If Not Dispatcher.CheckAccess Then : End If"
'Using Invoke Lambda
Invoke(Sub() Label1.Text = testText)
'Using Delegate
Dim updateLbl As UpdateLabelDelegate = AddressOf UpdateLabel
Invoke(updateLbl, testText)
Next
End Sub
End Class
第一个示例Invoke(Sub() Label1.Text = testText)
是我首选的方法,用于当需要在主线程上执行的代码量较小时,例如一行或两行。如果该行放在可能由主UI线程或不同场景中的后台线程调用的子中,那么它应该包含在If InvokeRequired Then
条件块中。第二个例子是使用委托,如果需要在主线程上执行更多行代码,这种方法会更好。这两种方法都允许您从将在主UI线程上执行的后台线程调用代码。
至于WPF,方法基本相同,但正如Bradley Uffner在评论中所指出的,调用将由Dispatcher
调用