簡體   English   中英

使用任務C#的ADODB並發問題

[英]ADODB Concurrence issue using task c#

我有一個for循環,在for循環內,我正在調用從SQL Server帶來數據的DB方法。 這很多,大約需要15秒。 我當時在想,也許我可以使用任務來優化它。

問題是當我使用任務時,我等待所有任務。 它給我帶來了與並發有關的問題,有時關閉了閱讀器,還有其他與連接有關的問題。

我從來不需要考慮這種情況,您介意檢查我的ADODB代碼以查看是否有一種方法可以使用該任務而不會出現並發問題嗎?

    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;
    }

這是我創建任務並等待所有任務的代碼。 函數data.getBudget是給我一些問題的函數:

   var getBudgetTask = new List<Task>();

        foreach (Checkbook c in list)
        {
            var getAcc = Task.Run(() =>
            {

                List<IAccount> accLst = new List<IAccount>();
                accLst = data.getAccounts(c.CheckbookID).ToList();
                ///for each account get the budget
                foreach (IAccount acc in accLst)
                {
                    IBudget actual = data.getBudget(c.CompanyNumber, "Actual", DateTime.Now.Year, acc.GLAccount);
                    IBudget budget = data.getBudget(c.CompanyNumber, "Budget", DateTime.Now.Year, acc.GLAccount);
                    for (int i = 1; i <= 12; i++)
                    {
                        string name = "Month" + i;
                        final[i - 1].Actual += decimal.Parse(budgetvariable.GetProperty(name).GetValue(actual).ToString());
                        final[i - 1].Budget += decimal.Parse(budgetvariable.GetProperty(name).GetValue(budget).ToString());
                    }
                }
            });

            getBudgetTask.Add(getAcc);
        }

        await Task.WhenAll(getBudgetTask);

謝謝,我將非常感謝您的幫助。

除非啟用了多個活動結果集 (MARS),否則每個連接一次僅允許一個活動SqlDataReader更多信息,請參見此處 )。
因此,您將不得不在每個任務中打開一個新的連接,而不是在各個任務之間共享cnxCRM

連接被合並,如果任務數量不是太大(幾十或幾十個但又不是更多),您的方法可能會奏效,那么您就有爭執的風險。

不能保證並行化會解決性能問題,尤其是如果並行化最終以針對相同表的相同執行計划為目標時。

除了@dlatikay的答案外,還要考慮到每個任務有一次數據庫往返,並且正在同一表的數據庫中創建並發。 通過一口氣告訴SQL Server所需的數據並允許SQL Server優化數據檢索策略,您可能會使用較少的計算資源。 這將涉及修改您的sp_Dashboard_GetBudget一次接受多個公司。

您沒有說明數據庫的大小,但是15秒鍾的時間似乎很長,無法檢索某些帳戶信息。 在SSMS中運行查詢,然后查看查詢計划。 有相當大的機會添加適當的索引將大大加快查詢速度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM