从SqlDataReader读取每个字段异步是否有任何好处?

时间:2013-11-10 20:46:51

标签: c# asynchronous ado.net

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

说我是否有以下内容:

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);

使用IsDBNullAsyncGetInt32Async等可以带来真正的好处吗?

2 个答案:

答案 0 :(得分:21)

在对反射器进行一些窥视之后,这里有趣的方法(GetFieldValueAsync<T>IsDBNullAsyncinternal方法GetBytesAsync)只对{{{{{{ 1}}场景。所以:如果你没有使用它:不要打扰 - 行数据已经缓存在内存中,CommandBehavior.SequentialAccess是纯粹的开销(尽管它至少是一个已经完成的任务结果,即{{ 1}} - 由Task<T>有效处理,没有上下文切换。)

答案 1 :(得分:3)

重复Marc撰写的内容以及官方ADO.NET docs的摘录-不幸的是,这些内容已移至Microsoft Blog Archives:

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

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