使用任务/多线程加载数据并显示UI

时间:2015-02-18 20:37:15

标签: vb.net multithreading task

所以我正在玩多线程。我有一个特定的表单,在从文件加载数据时会弹出一段时间。我的想法是在背景中加载数据,但仍然显示表单并在表单上显示一条消息,表明正在加载其他数据。

我已经完成了所有工作,但我不知道如何通知线程已完成,并准备将数据作为字典传递给我。

据我所知: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。

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

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

相反,你应该考虑异步和等待。使用C#5,在UI应用程序中运行后台工作变得更加容易。