在ASP.NET中异步填充DataSet或DataTable的最佳实践是什么?

时间:2014-08-28 22:00:36

标签: c# asynchronous ado.net dataadapter

鉴于以下代码,我对最佳实践提出了一些问题:

string connectionString = @"Server=(local)\sqlexpress; Database=master; Integrated Security=true;";

using (SqlConnection connection = new SqlConnection(connectionString))
{
    using (SqlDataAdapter dataAdapter = new SqlDataAdapter("select * from information_schema.columns", connection))
    {
        await connection.OpenAsync();

        DataTable dataTable = new DataTable();
        await Task.Run(() => dataAdapter.Fill(dataTable));
        return dataTable;
    }
}

我已经看过几个在Task.Run()调用中包装整个代码块的示例,但我不确定它是否比仅调用Task.Run()更好对于DataAdapter.Fill()方法,它感觉更灵活和特定(仅使用等待异步任务)。

在Fill()方法上调用Task.Run()的方法比包装整个代码块更好吗?

在Task.Run()中调用Fill()是否有任何负面影响?如果Fill()有错误,我会想到丢失调用堆栈和/或异常信息的内容。

有没有更好的方法在ASP.NET中编写它?

2 个答案:

答案 0 :(得分:1)

在ASP.NET中,使用Task.Run几乎没有帮助。究竟会改善什么?它只引入了开销。

也就是说,Fill将执行IO(耗尽数据读取器),因此可能想要异步调用它。不幸的是,这种方法没有异步版本。

如果您坚持使用异步IO(which is questionable for database access),则需要找到替代方案。也许异步实体框架或原始ADO.NET可以帮助您。

答案 1 :(得分:0)

您是否尝试过使用DataReader和新的ExecuteReaderAsync?我记得是SqlDataAdapter在没有异步的情况下在内部使用了DataReader。如果可能的话,您可能还想完全跳过使用DataTable来减少一些开销。

对于很少更改此类查询架构列的小型结果集,我可能会以多种方式之一将其缓存在Web服务器上。哎呀,对于架构更改,您甚至可以创建一个简单的DDL触发器来更新带有时间戳字段的单行表,以便让您知道已经进行了更改,然后只在必要时运行查询。对于除模式表之外的表,另一个选项是CHECKSUM_AGG。