使用 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 变得更加容易。
所以我正在玩多线程。我有一个特定的表单,在从文件加载数据时需要一段时间才能弹出。我的想法是在后台加载数据,但仍显示表单,并在表单上显示一条消息,显示正在加载其他数据。
我已完成所有操作,但我不确定如何收到线程已完成并准备好将数据作为字典传递给我的通知。
这是我所了解的: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 变得更加容易。