误用或错误的异步逻辑和等待C#使用ADO代码

问题描述 投票:0回答:1

我有一个web 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;
    }

我的Add Helper方法在哪里

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#中等待。

c# .net asynchronous ado
1个回答
0
投票

您不应该使用ADO公开的Async方法创建新任务。

此外,不是手动处理连接,而是将所有内容包装在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;  
}
© www.soinside.com 2019 - 2024. All rights reserved.