23

异步读取字段有什么好处吗?

说如果我有以下情况:

SqlDataReader reader = await cmd.ExecuteReaderAsync();
while (await reader.ReadAsync())
{
    try
    {
        if (reader.IsDBNull(COL_NAME))
        {
            continue;
        }

        user = new User();
        user.Id = reader.GetInt32(COL_ID);

IsDBNullAsync使用等会对现实世界有什么好处GetInt32Async吗?

4

2 回答 2

28

在看了一些反射器之后,这里有趣的方法(GetFieldValueAsync<T>IsDBNullAsyncinternal方法)只为场景GetBytesAsync做“有趣”的代码。CommandBehavior.SequentialAccess所以:如果你不使用它:不要打扰 - 行数据已经在内存中缓冲,并且Task<T>是纯粹的开销(尽管它至少是一个已经完成的任务结果,即Task.FromResult<T>- 由await,没有上下文切换)。

于 2013-11-10T21:20:00.390 回答
8

重复 Marc 所写的内容,其中包含来自官方ADO.NET 文档的片段- 不幸的是,该片段已移至 Microsoft 博客档案:

Read vs ReadAsync – 调用 ReadAsync 也是一个好主意:在非顺序模式下,这将读取所有列数据,这些数据可能跨越多个数据包,从而允许更快地访问列值。在顺序模式下,ADO.NET 将需要完成当前行的数据读取(如果尚未完全读取),并且某些 TDS 令牌可能位于行之间,然后可以异步读取这些令牌。

IsDBNull 和 GetFieldValue 与 IsDBNullAsync 和 GetFieldValueAsync- 如果您之前调用过 ReadAsync 并且正在使用非顺序访问,那么调用这些方法的同步版本将提供最佳性能,因为列数据已经被读取和处理(因此调用异步方法只会增加包装的开销任务中的值)。但是,如果您在非顺序访问模式下调用 Read,或者如果您正在使用顺序访问模式,那么做出决定会更加困难,因为您需要考虑需要读取多少数据才能到达所需的列以及多少数据该列可能包含。如果您已阅读上一列,并且目标列很小(如布尔、日期时间或数字类型),那么您可能需要考虑使用同步方法。或者,如果目标列很大(例如 varbinary(8000))或者您需要读取过去的大列,那么使用异步方法要好得多。最后,如果目标列很大(如 varbinary(MAX)、varchar(MAX)、nvarchar(MAX) 或 XML),那么您应该考虑新的GetStreamGetTextReaderGetXmlReader方法。

于 2020-03-15T18:03:02.680 回答