.net 第三方物流任务和存储过程
我想知道是否可以使用任务异步调用多个具有相同参数的不同存储过程,然后等待所有结果返回 我有以下资料:.net 第三方物流任务和存储过程,.net,c#-4.0,stored-procedures,asynchronous,task-parallel-library,.net,C# 4.0,Stored Procedures,Asynchronous,Task Parallel Library,我想知道是否可以使用任务异步调用多个具有相同参数的不同存储过程,然后等待所有结果返回 我有以下资料: private Task<DataTable> DataBaseCall(string procedureName, params Pair[] where) { DataTable data = new DataTable(); SqlConnection connection = new SqlConnection(connStr);
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.........
}
我有三个问题
有人能告诉我这是不是一个好方法吗?
这就是为什么my_finYear变量有时会被忽略,从而导致错误的原因。
我可以从任务返回数据表吗?
谢谢
迈克
这种方法从根本上说没有错。
您没有在代码中显示finYear来自何处,但根据您显示的代码,我看不出有任何理由无法将其正确传递到存储过程。
当然可以这样返回数据表。从多个线程并发访问是不安全的,但是可以跨线程进行访问,这没有问题。
代码中唯一的小错误是,在继续处理逻辑中应该有另一个try/finally,因为如果对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();
}
});
这种方法从根本上说没有错。
您没有在代码中显示finYear来自何处,但根据您显示的代码,我看不出有任何理由无法将其正确传递到存储过程。
当然可以这样返回数据表。从多个线程并发访问是不安全的,但是可以跨线程进行访问,这没有问题。
代码中唯一的小错误是,在继续处理逻辑中应该有另一个try/finally,因为如果对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.Hi的值,谢谢您的响应。我已经添加了如何传递上述变量。我只是将一个存储过程名数组和三个变量作为字符串传递,但由于某种原因,我得到了一个System.AggregateException错误,存储过程需要它。奇怪的我唯一能想到的猜测是,不知何故,你得到了一个_finYear的空值。如果在调试器下运行,当异常发生时,它应该会中断,您可以检查_finYear的值。