多线程DataTable计算只读VB或C#

时间:2017-08-29 18:51:54

标签: c# vb.net multithreading

我的代码在DataTable上进行了大约20次计算。我没有逐个进行计算,而是希望通过为每个计算设置一个单独的线程来加快进程。下面的代码简化了我实际做的事情,但它应该足以帮助我。

我发现以下网站和帖子类似,但我仍然无法推断我的情况 - 我为我的白痴道歉。

  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
  6. 我知道以下代码是"错误"因为我在确定线程完成之前中止每个线程。这是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;
        }
    }
    

1 个答案:

答案 0 :(得分: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