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

12

考虑以下代码,我有几个关于最佳实践的问题:

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()调用中的例子,但我不确定这是否比仅在DataAdapter.Fill()方法上调用Task.Run()更好,后者感觉更灵活和具体(只对异步任务使用await)。

调用Fill()方法时使用Task.Run()的方法是否比包裹整个代码块更好?

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

ASP.NET中是否有更好的编写方式?


1
为什么不将所有代码放在异步方法中?也就是说,将任务移动到包括整个SQL连接生命周期以及填充DataTable的范围内。 - user2864740
1
这是ASP.NET还是GUI? - usr
1
@AdrianAnttila 无论如何,就异常处理而言,请参见 - https://dev59.com/CG435IYBdhLWcg3wfgMf 异常被保留并传播到调用await的代码中,就像上下文一样。 - user2864740
1
Task.Run 几乎从不适用于 Web 应用程序。它确切地能够改善什么? - usr
3
通过并行处理请求可以提高性能,同时也创建了一个高度并发的服务器,因为该请求没有锁定,所以服务器可以在处理该请求时接受其他请求。因此,我相信当使用得当时,在某些情况下你可以获得优势。 - Oakcool
显示剩余3条评论
2个回答

1
在ASP.NET中,使用Task.Run几乎没有帮助。它到底能改进什么?它只会引入额外的开销。
话虽如此,Fill会执行IO(读取数据读取器),因此您可能需要异步调用它。不幸的是,这个方法没有异步版本。
如果您坚持使用异步IO(对于数据库访问来说是可疑的),您需要找到一种替代方法。也许异步Entity Framework或原始的ADO.NET可以帮助您。

0

你尝试过使用DataReader和新的ExecuteReaderAsync吗?我记得SqlDataAdapter已经在没有异步的情况下内部使用了DataReader。如果可能的话,您也可以考虑完全跳过使用DataTable以减少一些开销。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接