2017-08-29 74 views
1

我有一個代碼,在DataTable上做了大約20次計算。我不希望逐一進行計算,而是希望通過爲每次計算分別設置一個線程來加快進程。下面的代碼是我實際做的簡單模擬,但它應該足以幫助我。多線程DataTable計算只讀VB或C#

我發現以下類似的網站和帖子,但我仍然無法推斷我的情況 - 我爲我的白癡道歉。

  1. Multi Threading with Return value : vb.net
  2. MSDN: BackgroundWorker Class
  3. Multithreading calculations with state and mutable objects in a class
  4. Execute a statement after thread gets over
  5. MSDN: ManualResetEvent Class

我知道下面的代碼是 「錯誤的」,因爲我放棄每一個線程之前,我是放心的線程完了。這是BackgroundWorker類或ManualResetEvent類可能有用的地方。此外,實例化並運行GenerateValues函數中的線程會導致NULL對象引用錯誤;但實例化並運行CalculateSummary子例程中的線程正常工作。理想情況下,代碼實現將使用GenerateValues中的多個線程;但如果這是不可能的,那麼我可以完全刪除該函數並將其代碼添加到子例程中。爲了擴展我的目標受衆,我使用VB.NET(我實際使用的語言)和C#編寫了代碼。

VB.NET

Imports System.Threading 

Public Class GroupSummary 

    Public Sub CalculateSummary(ByVal pGroupKey As Integer) 

     Dim records As DataTable = Nothing ///actually calls code that reads a database. 
     Dim result As Integer = GenerateValues(records) 
     ///code that inserts result into a database. 
    End Sub 

    Private Function GenerateValues(ByVal pRecords As DataTable) As Integer 

     Dim numberHeightTall As Integer = 0 
     Dim numberWeightHeavy As Integer = 0 
     Dim numberFemale As Integer = 0 
     Dim numberBlueEyes As Integer = 0 
     Dim numberBob As Integer = 0 
     Dim thread1 As New Thread(Sub() numberHeightTall = 
          CInt(pRecords.Compute("Count(NameID)", "Height > 72"))) 
     Dim thread2 As New Thread(Sub() numberWeightHeavy = 
          CInt(pRecords.Compute("Count(NameID)", "Weight > 200"))) 
     Dim thread3 As New Thread(Sub() numberFemale = 
          CInt(pRecords.Compute("Count(NameID)", "Female = True"))) 
     Dim thread4 As New Thread(Sub() numberBlueEyes = 
          CInt(pRecords.Compute("Count(NameID)", "EyeColor = 'Blue'"))) 
     Dim thread5 As New Thread(Sub() numberBob = 
          CInt(pRecords.Compute("Count(NameID)", "Name = 'Bob'"))) 
     thread1.Start() 
     thread2.Start() 
     thread3.Start() 
     thread4.Start() 
     thread5.Start() 
     thread1.Abort() 
     thread2.Abort() 
     thread3.Abort() 
     thread4.Abort() 
     thread5.Abort() 

     Return numberHeightTall + numberWeightHeavy + numberFemale + numberBlueEyes + 
       numberBob 
    End Function 
End Class 

C#

using System.Threading; 
using System.Data; 
using System; 

public class GroupSummary { 

    public void CalculateSummary(int pGroupKey) { 

     DataTable records = null; ///actually calls code that reads a database. 

     int result = GenerateValues(records); 

     ///code that inserts result into a database. 
    } 
    private int GenerateValues(DataTable pRecords) { 

     int numberHeightTall = 0; 
     int numberWeightHeavy = 0; 
     int numberFemale = 0; 
     int numberBlueEyes = 0; 
     int numberBob = 0; 
     Thread thread1 = new Thread(delegate() { numberHeightTall = 
      Convert.ToInt32(pRecords.Compute("Count(NameID)", "Height > 72")); }); 
     Thread thread2 = new Thread(delegate() { numberWeightHeavy = 
      Convert.ToInt32(pRecords.Compute("Count(NameID)", "Weight > 200")); }); 
     Thread thread3 = new Thread(delegate() { numberFemale = 
      Convert.ToInt32(pRecords.Compute("Count(NameID)", "Female = True")); }); 
     Thread thread4 = new Thread(delegate() { numberBlueEyes = 
      Convert.ToInt32(pRecords.Compute("Count(NameID)", "EyeColor = 'Blue'")); }); 
     Thread thread5 = new Thread(delegate() { numberBob = 
      Convert.ToInt32(pRecords.Compute("Count(NameID)", "Name = 'Bob'")); }); 
     thread1.Start(); 
     thread2.Start(); 
     thread3.Start(); 
     thread4.Start(); 
     thread5.Start(); 
     thread1.Abort(); 
     thread2.Abort(); 
     thread3.Abort(); 
     thread4.Abort(); 
     thread5.Abort(); 

     return numberHeightTall + numberWeightHeavy + numberFemale + numberBlueEyes + 
       numberBob; 
    } 
} 
+3

看看C#的任務並行庫(TPL)(https://docs.microsoft.com/en-us/dotnet/standard/parallel - 編程/基於任務的異步編程)。 – KDecker

+0

@KDecker。我正在看它。謝謝! – basketballfan22

回答

1

按照從KDecker的建議,使用Task<TResult>類解決了我的問題。

以下是VB.NET實現:

Imports System.Data 

Public Class GroupSummary 

    Public Sub CalculateSummary(ByVal pGroupKey As Integer) 

     Dim records As DataTable = Nothing ///actually calls code that reads a database 
     Dim result As Integer = GenerateValues(records) 
     ///code that inserts result into database. 
    End Sub 

    Private Function GenerateValues(ByVal pRecords As DataTable) As Integer 

     Dim tasks(4) As Task(Of Integer) 
     tasks(0) = Task.Run(Function() CInt(pRecords.Compute(
             "Count(NameID)", "Height > 72"))) 
     tasks(1) = Task.Run(Function() CInt(pRecords.Compute(
             "Count(NameID)", "Weight > 200"))) 
     tasks(2) = Task.Run(Function() CInt(pRecords.Compute(
             "Count(NameID)", "Female = True"))) 
     tasks(3) = Task.Run(Function() CInt(pRecords.Compute(
             "Count(NameID)", "EyeColor = 'Blue'"))) 
     tasks(4) = Task.Run(Function() CInt(pRecords.Compute(
             "Count(NameID)", "Name = 'Bob'"))) 
     Task.WaitAll(tasks) 

     Return tasks(0).Result + tasks(1).Result + tasks(2).Result + tasks(3).Result + 
       tasks(4).Result 
    End Function 
End Class