使用 ADO 代码在 C# 中异步和等待的误解或错误逻辑
Misunderstood or Wrong Logic for Async and await in C# using ADO Code
我有一个网络 api 控制器获取操作,它在数据库代码中插入数据是
public async Task<HttpResponseMessage> Get(string UserName, string Password)
{
SqlParameter[] parameters = { new SqlParameter("@UserId", UserName), new SqlParameter("@Password", Password) };
AdoHelper DBHelper = new AdoHelper();
Company c = new Company();
await DBHelper.ExecDataSetProcAsync("[dbo].[usp_Insertuser]", parameters).ContinueWith(Task =>
{
DataSet ds = Task.Result;
if (ds != null && ds.Tables.Count == 1)
{
if (ds.Tables[0].Rows.Count >= 1)
{
}
}
ds.Dispose();
Task.Dispose();
});
HttpResponseMessage response = new HttpResponseMessage()
{
Content = new StringContent("ok", Encoding.UTF8, "text/plain")
};
return response;
}
我的 AdoHelper 方法是
public async Task<DataSet> ExecDataSetProcAsync(string qry, params object[] args)
{
DataSet ds = new DataSet();
return await Task<DataSet>.Factory.StartNew(
() =>
{
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(DBConnection.GetConnectionString())
{
AsynchronousProcessing = true
};
using (SqlConnection conn = new SqlConnection(builder.ConnectionString))
{
conn.Open();
using (SqlCommand cmd = CreateCommand(qry, CommandType.StoredProcedure, args))
{
cmd.Connection = conn;
var reader = cmd.ExecuteReader();
while (!reader.IsClosed)
ds.Tables.Add().Load(reader);
cmd.Connection.Close();
cmd.Connection.Dispose();
cmd.Dispose();
}
if (conn != null && conn.State == ConnectionState.Open)
{
conn.Close();
conn.Dispose();
}
}
return ds;
});
}
现在我正在调用此 Web api 控制器方法并希望在循环中插入 10,000 个用户的数据但它打开 147 与数据库的连接然后线程开始发送 500 个内部服务器错误我认为异步和等待任务没有正确关闭数据库连接。请告知我的实现出了什么问题,或者我是否误解了 C# 中的 Async 和 await。
您不应创建新任务,而应使用 ADO 公开的异步方法。
此外,不要手动处理连接,而是将所有内容包装在 using 语句中
public async Task<DataSet> ExecDataSetProcAsync(string qry, params object[] args)
{
var ds = new DataSet();
var builder = new SqlConnectionStringBuilder(DBConnection.GetConnectionString())
{
AsynchronousProcessing = true
};
using (var conn = new SqlConnection(builder.ConnectionString))
{
await conn.OpenAsync();
using (var cmd = CreateCommand(qry, CommandType.StoredProcedure, args))
{
cmd.Connection = conn;
using(var reader = await cmd.ExecuteReaderAsync())
{
if (await reader.ReadAsync())
{
while (await reader.ReadAsync())
{
ds.Tables.Add().Load(reader);
}
}
}
}
}
return ds;
}
我有一个网络 api 控制器获取操作,它在数据库代码中插入数据是
public async Task<HttpResponseMessage> Get(string UserName, string Password)
{
SqlParameter[] parameters = { new SqlParameter("@UserId", UserName), new SqlParameter("@Password", Password) };
AdoHelper DBHelper = new AdoHelper();
Company c = new Company();
await DBHelper.ExecDataSetProcAsync("[dbo].[usp_Insertuser]", parameters).ContinueWith(Task =>
{
DataSet ds = Task.Result;
if (ds != null && ds.Tables.Count == 1)
{
if (ds.Tables[0].Rows.Count >= 1)
{
}
}
ds.Dispose();
Task.Dispose();
});
HttpResponseMessage response = new HttpResponseMessage()
{
Content = new StringContent("ok", Encoding.UTF8, "text/plain")
};
return response;
}
我的 AdoHelper 方法是
public async Task<DataSet> ExecDataSetProcAsync(string qry, params object[] args)
{
DataSet ds = new DataSet();
return await Task<DataSet>.Factory.StartNew(
() =>
{
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(DBConnection.GetConnectionString())
{
AsynchronousProcessing = true
};
using (SqlConnection conn = new SqlConnection(builder.ConnectionString))
{
conn.Open();
using (SqlCommand cmd = CreateCommand(qry, CommandType.StoredProcedure, args))
{
cmd.Connection = conn;
var reader = cmd.ExecuteReader();
while (!reader.IsClosed)
ds.Tables.Add().Load(reader);
cmd.Connection.Close();
cmd.Connection.Dispose();
cmd.Dispose();
}
if (conn != null && conn.State == ConnectionState.Open)
{
conn.Close();
conn.Dispose();
}
}
return ds;
});
}
现在我正在调用此 Web api 控制器方法并希望在循环中插入 10,000 个用户的数据但它打开 147 与数据库的连接然后线程开始发送 500 个内部服务器错误我认为异步和等待任务没有正确关闭数据库连接。请告知我的实现出了什么问题,或者我是否误解了 C# 中的 Async 和 await。
您不应创建新任务,而应使用 ADO 公开的异步方法。
此外,不要手动处理连接,而是将所有内容包装在 using 语句中
public async Task<DataSet> ExecDataSetProcAsync(string qry, params object[] args)
{
var ds = new DataSet();
var builder = new SqlConnectionStringBuilder(DBConnection.GetConnectionString())
{
AsynchronousProcessing = true
};
using (var conn = new SqlConnection(builder.ConnectionString))
{
await conn.OpenAsync();
using (var cmd = CreateCommand(qry, CommandType.StoredProcedure, args))
{
cmd.Connection = conn;
using(var reader = await cmd.ExecuteReaderAsync())
{
if (await reader.ReadAsync())
{
while (await reader.ReadAsync())
{
ds.Tables.Add().Load(reader);
}
}
}
}
}
return ds;
}