【问题标题】:TPL Tasks & Stored proceduresTPL 任务和存储过程
【发布时间】:2011-08-10 08:24:39
【问题描述】:

我想知道是否可以通过使用任务异步调用多个具有相同参数的不同存储过程,然后等待所有结果返回。

我有以下几点:

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. 我可以从任务中返回数据表吗?

谢谢

迈克

【问题讨论】:

    标签: .net c#-4.0 stored-procedures asynchronous task-parallel-library


    【解决方案1】:
    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();                
        }
    });
    

    【讨论】:

    • 您好,感谢您的回复。我已经添加了如何传递上面的变量。我只是将存储过程名称的数组和三个变量作为字符串传递,但由于某种原因,我得到一个 System.AggregateException 错误,即存储过程需要 _finYear。奇怪!
    • 我能想到的唯一猜测是,您的 _finYear 有一个空值。如果您在调试器下运行,它应该会在异常发生时中断,您可以检查 _finYear 的值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-12
    • 2011-06-01
    • 1970-01-01
    • 2012-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多