使用任务c#的ADODB并发问题

时间:2017-09-20 20:01:02

标签: c# task adodb

我有一个for循环,在for循环中我调用了一个从SQL服务器带来数据的DB方法。 它很多,需要15秒。 我在想,也许我可以用任务来优化它。

问题是当我使用任务时,我等待所有任务。它给了我与并发相关的问题,有时读者关闭了,连接的其他问题。

我从来没有必要考虑这种情况,您是否介意检查我的ADODB代码以查看是否有一种方法可以在不出现并发问题的情况下使用该任务?

RedirectView

这是我创建任务并等待所有任务的代码。 函数data.getBudget是给我提出问题的函数:

    public  IBudget getBudget(int company, string tablename, int year, string account)
    {
        SqlCommand cmd1;
        int x = 1;
        if (tablename == "Actual")
            x = -1;
        Budget item;
        item = new Budget();
        try
        {
            cmd1 = new SqlCommand("sp_Dashboard_GetBudget", cnxCRM);
            cmd1.CommandType = CommandType.StoredProcedure;
            cmd1.Parameters.AddWithValue("@coNum", company);
            cmd1.Parameters.AddWithValue("@tablename", tablename);
            cmd1.Parameters.AddWithValue("@year", year);
            cmd1.Parameters.AddWithValue("@account", account);
            if( cnxCRM.State == ConnectionState.Closed)
            cnxCRM.Open();
            SqlDataReader sqlDataReader = cmd1.ExecuteReader();                
            if (sqlDataReader.HasRows)
            {
                while (sqlDataReader.Read())
                {

                    item.GLAccount = sqlDataReader["GLAccountNo"].ToString();
                    item.Month1 = float.Parse(sqlDataReader["Month1"].ToString()) * x;
                    item.Month2 = float.Parse(sqlDataReader["Month2"].ToString())* x;
                    item.Month3 = float.Parse(sqlDataReader["Month3"].ToString())* x;
                    item.Month4 = float.Parse(sqlDataReader["Month4"].ToString())* x;
                    item.Month5 = float.Parse(sqlDataReader["Month5"].ToString())* x;
                    item.Month6 = float.Parse(sqlDataReader["Month6"].ToString())* x;
                    item.Month7 = float.Parse(sqlDataReader["Month7"].ToString())* x;
                    item.Month8 = float.Parse(sqlDataReader["Month8"].ToString())* x;
                    item.Month9 = float.Parse(sqlDataReader["Month9"].ToString()) * x;
                    item.Month10 = float.Parse(sqlDataReader["Month10"].ToString())* x;
                    item.Month11 = float.Parse(sqlDataReader["Month11"].ToString())* x;
                    item.Month12 = float.Parse(sqlDataReader["Month12"].ToString()) * x;

                }
            }
        }
        catch (Exception ex)
        {
            if (cnxCRM.State == ConnectionState.Open)
            {
                cnxCRM.Close();
                throw ex;
            }
        }
        finally
        {
            //this.cnxCRM.Close();
        }
        return item;
    }

谢谢你,我真的很感激帮助。

2 个答案:

答案 0 :(得分:1)

除非启用多个活动结果集(MARS),否则每个连接(more info here)一次只允许一个活动SqlDataReader
因此,您必须在每个任务中打开一个新连接,而不是跨任务共享cnxCRM

连接是合并的,如果任务数量不是太大,几十或几十但不是更多,你的方法可能会解决,那么你就会冒着争用的风险。

无法保证并行化将解决性能问题,尤其是当它最终出现在针对同一个表的同一执行计划中时。

答案 1 :(得分:1)

除了@ dlatikay的回答之外,请考虑每个任务有一次数据库往返,并且您在同一个表的数据库中创建并发。通过告诉SQL Server一次性使用您想要的数据并允许SQL Server优化数据检索策略,您可能会使用较少的计算资源。这将涉及修改您的sp_Dashboard_GetBudget以同时接受多家公司。

您没有说明您的数据库有多大,但十五秒感觉非常长时间来检索一些帐户信息。在SSMS中运行查询并查看查询计划。添加适当的索引会大大加快查询速度。