TPL 任务和存储过程
我想知道是否可以通过使用任务异步调用具有相同参数的多个不同存储过程,然后等待所有结果返回。
我有以下问题:
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.........
}
我有三个问题。
- 谁能告诉我这是否是一个好方法?
- 任何想法都是为什么我的 _finYear 变量有时似乎被省略,这会导致错误。
- 我可以从任务中返回数据表吗?
谢谢迈克
I was wondering if it is possible to call a number of different stored procedures with the same parameters asynchronously by using tasks and then waiting for all the results to return.
I have the following:
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();
}
});
}
Which I call with:
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.........
}
I have three questions.
- Can anyone tell me if this is a good way to do this?
- Any idea's why my _finYear variable seems sometimes be omitted, which causes an error.
- Can I return the datatable from the task?
Thanks
Mike
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
DataTable
。从多个线程并发访问并不安全,但可以跨线程传递,没有问题。代码中唯一的小错误是,您应该在继续处理逻辑中再添加一个 try/finally,因为如果对
t.Result
的异步调用出现问题,t.Result
可能会抛出异常。 code>Begin/EndExecuteReader 这将使您无法处理命令和连接。所以这样会更好:DataTable
like that. It's not safe to access concurrently from multiple threads, but it can be handed across threads no problem.The only minor bug in your code is that you should have another try/finally in your continuation handling logic because it's possible for
t.Result
to throw an exception if there was a problem with the async call toBegin/EndExecuteReader
and that would leave you not disposing of the command and connection. So this would be better: