.net 在windows服务中使用TPL处理多线程(概念)
我有一个vb.net服务,它需要一些线程来分别处理每个函数调用并避免时间消耗 我有两个需要实现线程的函数: 在提问之前,以下是我的两个功能: 1-LaunchTasks():如果任务启动良好,它将计算此任务的“下一次数据”,否则将跳过它.net 在windows服务中使用TPL处理多线程(概念),.net,vb.net,multithreading,task-parallel-library,.net,Vb.net,Multithreading,Task Parallel Library,我有一个vb.net服务,它需要一些线程来分别处理每个函数调用并避免时间消耗 我有两个需要实现线程的函数: 在提问之前,以下是我的两个功能: 1-LaunchTasks():如果任务启动良好,它将计算此任务的“下一次数据”,否则将跳过它 'Dim oThread As Threading.Thread For Each oRow As DataRow In oDatatable.Rows Dim oCLASSE_Task As New CLASSE_Task If oCLASSE
'Dim oThread As Threading.Thread
For Each oRow As DataRow In oDatatable.Rows
Dim oCLASSE_Task As New CLASSE_Task
If oCLASSE_Task.Load(oRow.Item("Mytask")) Then
'oThread = New Threading.Thread(AddressOf oTask.launchSteps)
'oThread.Priority = Threading.ThreadPriority.Normal
'oThread.Start()
Dim oThread = System.Threading.Tasks.Task(Of Boolean).Factory.StartNew(Function() oCLASSE_Task.launchSteps())
End If
Next
' Need to wait until all threads finish
2-计算器数据()
我总是先调用LaunchTask(),然后调用calculateRunDates()(如果数据库中有新记录)
我必须等待函数LaunchTask()中的所有线程完成,然后才能启动calculateRunDates()
- 如何使用TPL(我以前从未使用过),比如thread.join(),来实现这一点
- 在这种情况下,我应该使用线程还是TPL
- 我如何在服务中使用TPL处理异常(类似这样的事情)
希望我足够清楚。要等待多个任务完成,可以使用task.WaitAll(…)方法。有关示例,请参见。 本文还展示了如何处理任务引发的异常。将try/catch放在Task.WaitAll()周围,并检查捕获的AggregateException以获取任务引发的个别异常
但是,使用Parallel.ForEach API似乎会使代码受益,它将提供更智能的循环分区。仅为每行创建一个单独的任务可能会使线程池过载。要等待多个任务完成,可以使用Task.WaitAll(…)方法。有关示例,请参见。 本文还展示了如何处理任务引发的异常。将try/catch放在Task.WaitAll()周围,并检查捕获的AggregateException以获取任务引发的个别异常
但是,使用Parallel.ForEach API似乎会使代码受益,它将提供更智能的循环分区。仅为每行创建单独的任务可能会使线程池过载。首先,回答您的问题: 如何使用TPL(我以前从未使用过),比如thread.join(),来实现这一点 你应该用这个。如果要等待几个
任务
s,可以使用
在这种情况下,我应该使用线程还是TPL
你应该使用第三方物流。它更容易使用,效率更高
如何在服务中使用TPL处理异常
如果任务
中的代码引发异常,然后您对该任务
执行Wait()
(或对多个任务
执行WaitAll()
),它将引发包含引发异常的aggregateeexception
。如果不调用Wait()
,则可以使用ContinueWith()
,正如链接到的问题所示
但对于您的代码,我认为更好的选择是使用:它将负责为您创建
任务
s,它将更有效地完成它(在迭代之间共享任务
s),并且您不必处理等待,因为当它返回时,所有迭代都已完成:
Parallel.ForEach(oDatatable.Rows.Cast(Of DataRow)(),
Sub(oRow)
Dim oCLASSE_Task As New CLASSE_Task
If oCLASSE_Task.Load(oRow.Item("Mytask")) Then
oCLASSE_Task.launchSteps()
End If
End Sub)
首先,回答您的问题: 如何使用TPL(我以前从未使用过),比如thread.join(),来实现这一点 你应该用这个。如果要等待几个
任务
s,可以使用
在这种情况下,我应该使用线程还是TPL
你应该使用第三方物流。它更容易使用,效率更高
如何在服务中使用TPL处理异常
如果任务
中的代码引发异常,然后您对该任务
执行Wait()
(或对多个任务
执行WaitAll()
),它将引发包含引发异常的aggregateeexception
。如果不调用Wait()
,则可以使用ContinueWith()
,正如链接到的问题所示
但对于您的代码,我认为更好的选择是使用:它将负责为您创建
任务
s,它将更有效地完成它(在迭代之间共享任务
s),并且您不必处理等待,因为当它返回时,所有迭代都已完成:
Parallel.ForEach(oDatatable.Rows.Cast(Of DataRow)(),
Sub(oRow)
Dim oCLASSE_Task As New CLASSE_Task
If oCLASSE_Task.Load(oRow.Item("Mytask")) Then
oCLASSE_Task.launchSteps()
End If
End Sub)
Parallel.ForEach将为您做什么,它将尝试创建最佳数量的并发任务来处理循环。此数字将接近您机器上的CPU内核数。这比只为每个DataRow创建一个任务要好,因为它减少了上下文切换,并且不会创建比在您的计算机上并发运行的线程多得多的线程。我将使用Parallel.ForEach(),它似乎更适合我的情况。@Volma使用many
Task
s很可能不会创建很多线程,因此不会导致上下文切换。但是您是对的,它比使用Parallel.ForEach()
@svick效率低。为什么不呢?线程的数量及其创建速率将由线程池控制,但它很可能比使用Parallel.ForEach()@Volma时大得多。使用Parallel.ForEach()
,使用的线程数也由ThreadPool
控制(除非您明确设置最大值),因此同样的规则适用。Parallel.ForEach将为您做什么,它将尝试创建最佳数量的并发任务来处理循环。此数字将接近您机器上的CPU内核数。这比只为每个DataRow创建一个任务要好,因为它减少了上下文切换,并且不会创建比在您的计算机上并发运行的线程多得多的线程。我将使用Parallel.ForEach(),它似乎更适合我的情况。@Volma使用manyTask
s很可能不会创建很多线程,因此不会导致上下文切换。但你是对的,它不是那么简单