0

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

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

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

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- 计算运行日期()

'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 处理异常(类似的东西)?

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

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

希望我足够清楚。

4

2 回答 2

2

首先,回答您的问题:

如何使用 TPL(我以前从未使用过)来做到这一点,比如 thread.join()?

你应该使用task.Wait()它。如果你想等待几个Tasks,你可以使用Task.WaitAll().

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

您应该使用 TPL。它更易于使用且更高效。

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

如果 a 中的代码Task抛出异常,然后你Wait()在那个Task(或WaitAll()多个Tasks 上),它将抛出AggregateException包含抛出的异常。如果您不致电Wait(),则可以使用ContinueWith(),正如您链接到的问题所暗示的那样。


但是对于您的代码,我认为更好的选择是使用Parallel.ForEach():它将负责Task为您创建 s,它会更有效地完成它(它Task在迭代之间共享 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)
于 2012-08-13T19:03:50.543 回答
1

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

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

于 2012-08-13T19:01:43.027 回答