簡體   English   中英

TPL 任務和存儲過程

[英]TPL Tasks & Stored procedures

我想知道是否可以通過使用任務異步調用許多具有相同參數的不同存儲過程,然后等待所有結果返回。

我有以下內容:

private Task<DataTable> DataBaseCall(string procedureName, params Pair[] where)
    {
        DataTable data = new DataTable();
        SqlConnection connection = new SqlConnection(connStr);

        SqlCommand command = new SqlCommand(procedureName, connection);
        connection.Open();

        for (int i = 0; i < where.Length; i++)
        {
            command.Parameters.Add(where[i].First.ToString(), where[i].Second.ToString());
        }

        var readerTask = Task<SqlDataReader>.Factory.FromAsync(command.BeginExecuteReader, command.EndExecuteReader, null);
        return readerTask.ContinueWith(t =>
            {
                var reader = t.Result;
                try
                {
                    reader.Read();
                    data.Load(reader);
                    return data;
                }
                finally
                {
                    reader.Dispose();
                    command.Connection.Close();
                    command.Connection.Dispose();
                    command.Dispose();
                }
            });
    }

我打電話給:

private void SetReportVariables(string reportName, string[] storedProcedureName, string _clientGroup, string _clientCode, string _finYear, string _period)
    {
       Task[] tasks = new Task[storedProcedureName.Length];

        for (int i = 0; i < storedProcedureName.Length; i++)
        {
            List<Pair> parameters = new List<Pair>();
            parameters.Add(new Pair("@ClientGroup", _clientGroup));
            parameters.Add(new Pair("@ClientCode", _clientCode));
            parameters.Add(new Pair("@FinYear", _finYear));

            tasks[i] = DataBaseCall(storedProcedureName[i], parameters.ToArray());
        }
        Task.WaitAll(tasks);

        ...........Do something with the DataTables.........
    }

我有三個問題。

  1. 誰能告訴我這是否是一個好方法?
  2. 任何想法都是為什么我的 _finYear 變量有時會被省略,這會導致錯誤。
  3. 我可以從任務中返回數據表嗎?

謝謝

麥克風

  1. 這種方法從根本上沒有錯。
  2. 您沒有在代碼中顯示 _finYear 的來源,但根據您顯示的代碼,我看不出有任何理由無法將其正確傳遞給存儲過程。
  3. 當然,您可以像這樣返回DataTable 從多個線程並發訪問是不安全的,但是可以跨線程傳遞沒有問題。

代碼中唯一的小錯誤是,您應該在繼續處理邏輯中再嘗試/最終,因為如果對Begin/EndExecuteReader的異步調用出現問題, t.Result可能會引發異常,這會讓您離開不處理命令和連接。 所以這會更好:

readerTask.ContinueWith(t =>            
{                
    try
    {
        var reader = t.Result;                

        try                
        {                    
            reader.Read();
            data.Load(reader);

            return data;
        }
        finally
        {                    
            reader.Dispose();
        }            
    }
    finally
    {
        command.Connection.Close();
        command.Connection.Dispose();
        command.Dispose();                
    }
});

暫無
暫無

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

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