所以我正在玩多线程。我有一个特定的表单,在从文件加载数据时会弹出一段时间。我的想法是在背景中加载数据,但仍然显示表单并在表单上显示一条消息,表明正在加载其他数据。
我已经完成了所有工作,但我不知道如何通知线程已完成,并准备将数据作为字典传递给我。
据我所知: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。
答案 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应用程序中运行后台工作变得更加容易。