如何在主线程上做点什么?

时间:2017-11-03 15:29:02

标签: vb.net multithreading

我曾经是一名xcode程序员。

在创建应用程序时,我倾向于在其他线程上做大部分事情。

偶尔,例如当我想访问UI线程时,我会在主线程上做一些事情。

说我做了

//在网络上加载一些繁重的资源 doOnMainThread(sub()updateUIandStuff()) //继续做其他事情。

我如何在VB中实现doOnMainthread?

很久以前,在objective-c中有一种简单的方法可以做到这一点。如何在vb.net中这样做

1 个答案:

答案 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

调用