我有一些使用SqlConnection创建临时表(例如#Foo)的C#代码,调用存储过程来填充那些临时表并将结果返回给C#客户端,使用c#对这些结果执行复杂计算,并使用计算结果更新之前创建的临时表之一.
由于整个过程中使用的临时表,我们必须只有一个SqlConnection.
我发现了使用计算结果更新临时表时的性能瓶颈.此代码已经对更新进行批处理,以防止C#客户端内存不足.每批计算数据通过SqlCommand.ExecuteNonQuery发送到存储过程,然后sproc会更新临时表.代码将大部分时间花在对ExecuteNonQuery的调用上.
因此,我将其更改为BeginExecuteNonQuery,以及在线程上等待并调用EndExecuteNonQuery的代码.这提高了性能约三分之一,但我担心使用相同的SqlConnection对SqlCommand.BeginExecuteNonQuery进行多次并发调用.
这样可以,还是会遇到线程问题?
很抱歉很长的解释.
MSDN文档声明:
BeginExecuteNonQuery方法立即返回,但在代码执行相应的EndExecuteNonQuery方法调用之前,它不能执行任何其他对同一SqlCommand对象启动同步或异步执行的调用.
这似乎意味着不同的SqlCommand对象可以在第一个SqlCommand完成之前调用BeginExecuteNonQuery.
以下是一些说明问题的代码:
private class SqlCommandData
{
public SqlCommand Command { get; set; }
public IAsyncResult AsyncResult { get; set; }
}
public static void TestMultipleConcurrentBeginExecuteNonQueryCalls(string baseConnectionString)
{
var connectionStringBuilder = new SqlConnectionStringBuilder(baseConnectionString)
{
MultipleActiveResultSets = true,
AsynchronousProcessing = true
};
using (var connection = new SqlConnection(connectionStringBuilder.ConnectionString))
{
connection.Open();
// ELIDED - code that uses connection to do various Sql work
SqlDataReader dataReader = null;
// in real code, this would be initialized …Run Code Online (Sandbox Code Playgroud)