分类
编程

VB.Net 常用多线程处理方式总结

从 WinForm 到 WPF 再到 UWP,我们能看到微软在 .Net 设计方面的进步。多线程处理所需编写的代码量越来越少。我以 Visual Basic 为例,介绍两种最常用、最简单易用的的多线程处理方法。

函数不需要在执行过程中返回结果或进度

可以使用 Await 和 Async 关键字。用 Async 修饰一个函数,即可将其标记为异步函数。调用时在函数名前加 Await,就可以在保持 UI 线程相应的情况下,等待异步函数完成执行。请看例子:

Public Async Function HeavyWorkAsync() As Task(Of String)
    Dim web As New Net.WebClient
    Await web.DownloadStringAsync("http://some.thing")
    Await Task.Run(
        Sub()
            System.Threading.Thread.Sleep(5000)
        End Sub)
    Return "Done"
End Function

Private Async Sub btn_Click(sender As Object, e As EventArgs)
    btn.IsEnabled = False
    btn.Content = "Wait"
    Dim ret As String
    ret = Await HeavyWorkAsync()
    btn.Content = ret
    btn.IsEnabled = True
End Sub

在按钮被点按后,在执行到 ret = Await HeavyWork()  时,UI 线程会继续响应,但是函数会等待异步操作执行完后继续进行。

正如你所见,每个异步函数的名字会以 “Async” 结尾,同时每个异步函数中至少包含一个 Await 语句。如果异步返回值,那他会返回一个 Task(Of 异步函数需要返回值的类型) 。 这些正是一个异步函数所必要的部分。

如果你要进行的费时步骤提供了异步函数,那就使用 Await DoSomethingAsync() 。如果没有提供异步函数,那就放到 Await Task.Run() 块中。

有关 Async / Await 异步编程的详细内容,请参阅:
https://docs.microsoft.com/zh-cn/dotnet/visual-basic/programming-guide/concepts/async

函数需要在执行过程中返回值或进度

这种情况可以使用事件。可以看下面的例子:

' 主窗体
Public Class MainWindow
    Private WithEvent web As New WebOps
    ' 省略创建线程来执行 WebOps 类 GetResponse() 方法的内容
    Private Sub ProgressUpdateHandler(value As Integer) 
      Handles web.ProgressUpdate
        Me.Dispatcher.Invoke(New Action(
            Sub()
                progressBar.Value = value
            End Sub)
    End Sub
End Class

' 类
Public Class WebOps
    Public Event ProgressUpdate(value As Integer)
    Public Sub GetResponse()
        ' 执行一些步骤...
        RaiseEvent ProgressUpdate(35)
        ' 执行另一些步骤...
        RaiseEvent ProgressUpdate(65)
    End Sub
End Class

创建一个进度更新的事件,通过在一个方法内多次触发,并在 UI 线程内创建事件处理函数,即可在函数在另一个线程内执行时,即时返回执行进度。

当然还可以创建一个执行完后触发的事件,在执行完成后触发。

发表评论

电子邮件地址不会被公开。 必填项已用*标注