在Windows服务中使用TPL处理多线程(概念)

时间:2012-08-13 18:39:35

标签: .net vb.net multithreading task-parallel-library

我有一个vb.net服务需要一些线程来单独处理每个函数调用,并避免耗费时间。

我有两个需要实现线程的函数:

在提出我的问题之前,这是我的两个功能:

1- LaunchTasks():如果任务启动良好,它会为此任务计算'NextRunDate',否则会跳过它。

'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- calculateRunDates()

'It's called for each object in CLASSE_Task

'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

        Dim oThreadTask = System.Threading.Tasks.Task(Of Boolean).Factory.StartNew(Function() oCLASSE_Task.calculateNextRunDate())

        'oThread = New Threading.Thread(AddressOf oTask.calculateNextRunDate)
        'oThread.Priority = Threading.ThreadPriority.Normal
        'oThread.Start()

    End If
Next
' Need to wait until all threads finish

我总是首先调用LaunchTask()然后调用calculateRunDates()(如果我在数据库中获得新记录)。

在启动calculateRunDates()之前,我必须等待函数LaunchTask()中的所有线程完成。

  • 我怎样才能使用TPL(之前从未使用过),像thread.join()?

  • 在这种情况下我应该使用线程还是TPL?

  • 如何在服务中使用TPL处理异常(类似于that)?

注意:我在使用SyncLock的CLASSE_Task中有锁。

没有足够的例子使用vb.net,主要是C#。

希望我足够清楚。

2 个答案:

答案 0 :(得分:2)

首先,回答你的问题:

  

我怎样才能使用TPL(我以前从未使用过它),像thread.join()?

您应该使用task.Wait()。如果您想等待多个Task,则可以使用Task.WaitAll()

  

在这种情况下我应该使用线程还是TPL?

您应该使用TPL。它更容易使用,效率更高。

  

如何在服务中使用TPL处理异常?

如果Task中的代码引发了异常,然后您Wait()上的Task(或多个WaitAll()上的Task),它将会抛出包含抛出异常的AggregateException。如果您不致电Wait(),则可以使用ContinueWith()作为您链接的问题建议。


但是对于您的代码,我认为更好的选择是使用Parallel.ForEach():它会为您创建Task,它会更有效地执行(它共享{{迭代之间的迭代)并且您不必处理等待,因为当它返回时,所有迭代都完成了:

Task

答案 1 :(得分:1)

要等待完成多个任务,您可以使用Task.WaitAll(...)方法。有关示例,请参阅this。 本文还介绍了如果任务抛出异常,如何处理异常。在try.WaitAll()周围放置try / catch并检查捕获的AggregateException以获取任务抛出的各个异常。

但是,看起来你的代码会受益于使用Parallel.ForEach API,它将提供更智能的循环分区。简单地为每一行创建一个单独的Task可能会使线程池重载。