0

我想循環一個數據表與更多然後100 000行使用平行對於每個。一切工作正常,大約25000次迭代。我沒有得到任何錯誤,我看到應用程序仍在工作,但它有點阻擋,沒有發生。我試圖將這個循環封裝在一個factory.startnew中,我毫無理由地在大約5000次迭代中得到了一個隨機的異常期望。並行爲每一個進入DeadLock

Dim lstExceptions As New ConcurrentQueue(Of Exception) 
Dim options As New ParallelOptions 
options.MaxDegreeOfParallelism = 3 

Parallel.ForEach(ReservationReportDS.Tables(0).AsEnumerable(), options, 
    Sub(row) 
     Try 
      Dim tmpRow As DataRow = CType(row, DataRow) 
      Dim ReservationID As Integer = tmpRow.Field(Of Integer?)("autNoReservation") 
      Dim customerID As Integer = tmpRow.Field(Of Integer?)("CustomerID") 
      Dim VehiculeID As Integer = tmpRow.Field(Of Integer?)("autNoVehicule") 

      Dim bill As New BillingPath() 
      bill.Calculate_Billing(ReservationID, customerID, VehiculeID) 

     Catch err As Exception 
      lstExceptions.Enqueue(err) 
     End Try 
    End Sub 
) 

If (lstExceptions.Count > 0) Then 
    Throw New AggregateException(lstExceptions) 
End If 

Catch errAgg As AggregateException 
    For Each ex As Exception In errAgg.InnerExceptions 
     Log(Log_Billing_UI, "", System.Reflection.MethodBase.GetCurrentMethod().Name & GetExceptionInfo(ex)) 
    Next 
Catch ex As Exception 
    Log(Log_Billing_UI, "", System.Reflection.MethodBase.GetCurrentMethod().Name & GetExceptionInfo(ex)) 
End Try 
+0

您可以添加錯誤堆棧跟蹤 – Massanu

+0

1)'bill.Calculate_Billing'是否寫入DataSet? 2)數據庫的設計經過精心研究,可以爲這類事情工作,所以它可能是一個很好的選擇。另外,數據庫中的數據是持久的。 –

+0

沒有錯誤,它只是簡單的阻止。沒有線程使用相同的數據很好。 1)是的Calculate_Billing會做1插入95%的時間,5%2或3.但通話使許多選擇(至少10) –

回答

2

既然你的記錄,從而量,我想推薦你考慮以下概念:

  1. 閱讀所有記錄到ConcurrentQueue(中SomeBillingInfoClass)收集第一 - 它將使你不能保持與DB打開的連接,用數據庫中的數據進行線程安全的休息操作。
  2. 在裏面創建任務與計費calc代碼列表。這將允許您並行運行任務並輕鬆地從#1傳遞ConcurrentQueue變量。
  3. 保持任務在循環中運行,同時ConcurrentQueue中至少有一個元素保留。
  4. 如果您可以將計費計算結果聚合到其他類 - 您可以使用附加的線程安全ConcurrentQueue(Of BillingCalcResultInfoClass)集合來完成。
  5. 畢竟計算完畢後 - 在單線程和單個長事務中寫入數據庫 - 這可能會更快,然後精細寫入數據庫。

你的代碼的一些注意事項 - 我想你可能不需要手動扔AggregateException - .NET環境將自動爲您代勞。你只需要在.ContinueWith()方法的任務(抱歉,主要是我的C#開發人員和使用C#符號)。

我用類似的方法來處理數百萬條記錄,它工作正常。通常我使用3-5個任務。但你總是可以研究你可能有多少任務。

使用ConcurrentQueue或類似的線程安全集合將允許您更輕鬆地保證您的代碼線程安全。

如果您有任何問題,請讓我知道。

+0

我嘗試使用任務列表,它看起來像現在工作。對於每個條目,我現在要創建一個完整的CPU使用率爲100%的任務。 Il試着創造一個只有幾個任務的算法,看看它是否有效 –

+0

@Max_Thom,是的。您可以加載某些線程安全集合中的所有記錄。運行幾個任務,然後在每個任務調用collection.TryDequeue方法內彈出下一條記錄。而且這些任務應該在無限循環內運行,只有在集合中沒有記錄時纔會中斷循環。通過這種方式,您只能同時處理多個任務,並且不會有100%的CPU使用率。 –

0

謝謝大家的回答,特別是Anton Norko。我終於找到了問題,它在我身邊。在某些情況下,Calculate_Billing陷入無限循環。由於我同時使用了3個線程,他們一個接一個地卡住了。

相關問題