等待使用可等待的方法迭代数据表
Await iterating a datatable with awaitable methods
我有以下异步方法,它等待每行 babsis 上的单独方法。我终其一生都无法弄清楚如何将其提升到一个新的水平,并等待处理整个数据表(即让所有行一起开始,而不是一次一个)。任何帮助将不胜感激。
Public Async Function GetLabResultPanelPackByPRN_Async(ByVal ClientID As Integer, ByVal PRN As Integer, ByVal SamplePointID As Integer, ByVal StartDate As DateTime, ByVal EndDate As DateTime, ByVal InequalityMode As InequalityModes) As Task(Of List(Of LabResultPanelPack))
Dim LRPPs As New List(Of LabResultPanelPack)
Dim ta As New eniCIP_DataTableAdapters.proc_WebPortal_ResultsByPRNTableAdapter
Dim dt As New eniCIP_Data.proc_WebPortal_ResultsByPRNDataTable
ta.Fill(dt, PRN)
For Each row As eniCIP_Data.proc_WebPortal_ResultsByPRNRow In dt
Dim LRPP As New LabResultPanelPack
LRPP.LabResult = GetLabResultByPRNFromRow(row, InequalityMode)
Dim ResultsByDetAndSPTask As Task(Of List(Of LabResultExtended)) = GetResultsByDetAndSP_Async(ClientID, SamplePointID, row.lDetID, StartDate, EndDate, InequalityMode)
Dim ResultsBySampleTypeAndDetTask As Task(Of List(Of LabResultExtended)) = GetResultsBySampleTypeAndDet_Async(ClientID, row.lSampleTypeID, row.lDetID, StartDate, EndDate, InequalityMode)
Dim ResultsBySampleTypeGroupAndDetTask As Task(Of List(Of LabResultExtended)) = GetResultsBySampleTypeGroupAndDet_Async(ClientID, row.lSampleTypeGroupID, row.lDetID, StartDate, EndDate, InequalityMode)
LRPP.HistoricResultsByDetAndSP = Await ResultsByDetAndSPTask
LRPP.HistoricResultsByDetAndSampleType = Await ResultsBySampleTypeAndDetTask
LRPP.HistoricResultsByDetAndSampleTypeGroup = Await ResultsBySampleTypeGroupAndDetTask
LRPPs.Add(LRPP)
Next
Return LRPPs
End Function
这种情况下的解决方案是简单地添加一个函数,事情很快就会解决。
如果您创建一个新函数来处理 one 行,如下所示:
Private Async Function ProcessRow(row As YourRowType, ...) As Task(Of LabResultPanelPack)
Dim LRPP As New LabResultPanelPack
LRPP.LabResult = GetLabResultByPRNFromRow(row, InequalityMode)
'Add your tasks for processing the row further
Return LRPP
End Function
现在你的主循环看起来像这样:
For Each row As eniCIP_Data.proc_WebPortal_ResultsByPRNRow In dt
Dim LRPP = Await ProcessRow(row, ...)
LRPPs.Add(LRPP)
Next
此时您可以将 LRPPs
列表更改为
Dim LRPPTasks As New List(Of Task(Of LabResultPanelPack))
并将循环更改为
For Each row As eniCIP_Data.proc_WebPortal_ResultsByPRNRow In dt
Dim LRPPTask = ProcessRow(row, ...)
LRPPTasks.Add(LRPPTask)
Next
这样您就可以避免等待每一行,并在到达 ProcessRow
函数中的第一个 await
后立即继续处理这些行。
最后您需要做的就是将 return 更改为
Return Await Task.WhenAll(LRPPTasks)
大功告成。
作为一个小补充:按照我的建议重写代码后,您最终会得到 Function
中唯一的 Await
。这意味着您可以从函数中删除 Async
标志,并从 Return
中删除 Await
。这样你的开销就会少一些。
我有以下异步方法,它等待每行 babsis 上的单独方法。我终其一生都无法弄清楚如何将其提升到一个新的水平,并等待处理整个数据表(即让所有行一起开始,而不是一次一个)。任何帮助将不胜感激。
Public Async Function GetLabResultPanelPackByPRN_Async(ByVal ClientID As Integer, ByVal PRN As Integer, ByVal SamplePointID As Integer, ByVal StartDate As DateTime, ByVal EndDate As DateTime, ByVal InequalityMode As InequalityModes) As Task(Of List(Of LabResultPanelPack))
Dim LRPPs As New List(Of LabResultPanelPack)
Dim ta As New eniCIP_DataTableAdapters.proc_WebPortal_ResultsByPRNTableAdapter
Dim dt As New eniCIP_Data.proc_WebPortal_ResultsByPRNDataTable
ta.Fill(dt, PRN)
For Each row As eniCIP_Data.proc_WebPortal_ResultsByPRNRow In dt
Dim LRPP As New LabResultPanelPack
LRPP.LabResult = GetLabResultByPRNFromRow(row, InequalityMode)
Dim ResultsByDetAndSPTask As Task(Of List(Of LabResultExtended)) = GetResultsByDetAndSP_Async(ClientID, SamplePointID, row.lDetID, StartDate, EndDate, InequalityMode)
Dim ResultsBySampleTypeAndDetTask As Task(Of List(Of LabResultExtended)) = GetResultsBySampleTypeAndDet_Async(ClientID, row.lSampleTypeID, row.lDetID, StartDate, EndDate, InequalityMode)
Dim ResultsBySampleTypeGroupAndDetTask As Task(Of List(Of LabResultExtended)) = GetResultsBySampleTypeGroupAndDet_Async(ClientID, row.lSampleTypeGroupID, row.lDetID, StartDate, EndDate, InequalityMode)
LRPP.HistoricResultsByDetAndSP = Await ResultsByDetAndSPTask
LRPP.HistoricResultsByDetAndSampleType = Await ResultsBySampleTypeAndDetTask
LRPP.HistoricResultsByDetAndSampleTypeGroup = Await ResultsBySampleTypeGroupAndDetTask
LRPPs.Add(LRPP)
Next
Return LRPPs
End Function
这种情况下的解决方案是简单地添加一个函数,事情很快就会解决。
如果您创建一个新函数来处理 one 行,如下所示:
Private Async Function ProcessRow(row As YourRowType, ...) As Task(Of LabResultPanelPack)
Dim LRPP As New LabResultPanelPack
LRPP.LabResult = GetLabResultByPRNFromRow(row, InequalityMode)
'Add your tasks for processing the row further
Return LRPP
End Function
现在你的主循环看起来像这样:
For Each row As eniCIP_Data.proc_WebPortal_ResultsByPRNRow In dt
Dim LRPP = Await ProcessRow(row, ...)
LRPPs.Add(LRPP)
Next
此时您可以将 LRPPs
列表更改为
Dim LRPPTasks As New List(Of Task(Of LabResultPanelPack))
并将循环更改为
For Each row As eniCIP_Data.proc_WebPortal_ResultsByPRNRow In dt
Dim LRPPTask = ProcessRow(row, ...)
LRPPTasks.Add(LRPPTask)
Next
这样您就可以避免等待每一行,并在到达 ProcessRow
函数中的第一个 await
后立即继续处理这些行。
最后您需要做的就是将 return 更改为
Return Await Task.WhenAll(LRPPTasks)
大功告成。
作为一个小补充:按照我的建议重写代码后,您最终会得到 Function
中唯一的 Await
。这意味着您可以从函数中删除 Async
标志,并从 Return
中删除 Await
。这样你的开销就会少一些。