Web服务中的多线程,以加快处理速度

时间:2016-08-18 07:56:47

标签: c# asp.net multithreading

我在桌面程序中有一个业务逻辑处理。

然而,当我处理大数据时,数据处理速度很慢(我正在使用MS SQL数据库)。因此,我做了一个解决方案。我打开一个Web服务项目,将我的业务逻辑流程打包成一个dll名称consoleAttn(),然后将处理分成几个Threading,使用DotNet Task.Parallel技术作为下面的代码:

`

    DataTable dtEmp = new DataTable("Employee");

    if (cn.State == ConnectionState.Closed)
    {
        cn.Open();
    }

    using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(sEmpQuery, cn))
    {
        Console.Write(string.Format("Command Text:{0}", sEmpQuery));
        cmd.Parameters.AddWithValue("Period", sPeriod);
        dtEmp.Load(cmd.ExecuteReader());
    }

    if (cn.State == ConnectionState.Open)
    {
        cn.Close();
    }

    Int32 iThread;
    iThread = iNoThread;

    Int32 iCountTable;
    iCountTable = dtEmp.Rows.Count;
    Console.WriteLine(string.Format("Total Rows:{0}", iCountTable));

    Int32 IProcNum;
    IProcNum = iCountTable / iThread;
    Console.WriteLine(string.Format("Transaction no:{0}", IProcNum));


    if (iCountTable < iThread)
    {
        Boolean bl;

        AutoHRPay.frmClosePeriod aPay= new AutoHRPay.frmClosePeriod();

        MiscResource AMisc = new MiscResource();
        MiscResource misc = new MiscResource();

        misc.SetDBConn(strCN);


    }
    else
    {
        Boolean[] bl = new Boolean[iThread];

        object locker = new object();

        Parallel.For(1, iThread + 1, i =>
        {
            System.Text.StringBuilder strSQL = new System.Text.StringBuilder();
            strSQL.Append("(");

            DataTable dtEmpThread = dtEmp.Clone();
            dtEmpThread.Clear();

            for (Int32 j = ((i - 1) * IProcNum + 1); j <= ((i != iThread) ? (IProcNum * i) : iCountTable); j++)
            {
                dtEmpThread.ImportRow(dtEmp.Rows[j-1]);
            }



            int row_counter = 0;

            lock (locker)
            {
                row_counter++;
                streamwriter.WriteLine("Processing row: {0}", row_counter);
            }


            ConsoleAttn aPay = new ConsoleAttn();

            aPay.runConsole();

        });


    }
    streamwriter.Close();
    return "Completed.";

1)您是否有任何想法,当我需要停止进程或调用Web服务的客户端崩溃时,我应该如何进行异步处理?

1 个答案:

答案 0 :(得分:0)

有几种方法可能会有所帮助,特别是如果您正在讨论要处理的数据量

  • 不要在巨大的DataTable中立即从SQL Server加载所有内容
  • 不要克隆DataTable

首先,如果数据集非常大,则需要花费时间将此数据从SQL服务器传输到您的计算机。然后,在处理时,此数据集需要大量内存。使用多个线程,您可以有效地复制整个大数据集。高内存使用会导致不必要的垃圾回收和更差的应用程序性能,尤其是在服务器没有大量内存的情况下。存在交换的风险,您的表现将被破坏。

如果数据行处理顺序并不重要,并且每行都可以独立处理,那么你可以这样:

  • 使用DataReader逐记录读取数据
  • 将此数据存储在某些线程安全集合中
  • 在阅读数据时,您可以通过多个线程开始处理

可能你会想要使用LinkedList集合来增加和删除项目的O(1)复杂度。不要忘记对此集合的线程安全访问。 在这种情况下,您将获得什么好处:

  • 收到SQL Server的第一个字节后立即开始处理
  • 处理期间内存使用量减少。您不需要多次存储某些数据,在等待处理其他数据时,不需要存储已处理的数据。

根据数据的典型大小,SQL服务器配置,服务器内存量等,您可能希望尽快从SQL加载所有数据或加载数据有一些延迟,以确保您的数据没有太多未处理的记录集合。