使用 Tasks/Multi-Thread 加载数据并显示 UI

Use Tasks/Multi-Thread to load data and show UI

所以我正在玩多线程。我有一个特定的表单,在从文件加载数据时需要一段时间才能弹出。我的想法是在后台加载数据,但仍显示表单,并在表单上显示一条消息,显示正在加载其他数据。

我已完成所有操作,但我不确定如何收到线程已完成并准备好将数据作为字典传递给我的通知。

这是我所了解的:P

Dim t1 As Task(Of Dictionary(Of String, Double()))

Private Sub cbchannels_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cbchannels.SelectedIndexChanged
    t1 = Task(Of Dictionary(Of String, Double())).Factory.StartNew(Function() Load_Data())
End Sub

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    If t1.IsCompleted Then
        data = t1.Result
    End If
End Sub

我知道任务可以检查是否完成并获取结果

 t1.IsCompleted
 t1.Result

使用计时器不断检查任务是否完成是唯一的方法吗? 我在做什么有意义吗? 我不想使用 BackgroundWorker。

虽然这不是唯一的方法,但最简单的选择可能是使用 BackgroundWorker。您调用 RunWorkerAsync 将其关闭并在 DoWork 事件处理程序中完成工作。完成后,将数据分配给 e.Result 属性。然后,您可以在 RunWorkerCompleted 事件处理程序的 UI 线程上取回它。例如

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    BackgroundWorker1.RunWorkerAsync()
End Sub

Private Sub BackgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    Dim table As DataTable = GetData()

    e.Result = table
End Sub

Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    Dim table = DirectCast(e.Result, DataTable)

    'Use table here.
End Sub

那个计时器很聪明。幸运的是有一个直接是得到通知。您可以在任何 Task 上调用 ContinueWith 以注册在该任务完成时调用的回调。这回答了你的问题。

相反,您应该研究异步和等待。 运行 UI 应用程序的后台工作使用 C# 5 变得更加容易。