繁体   English   中英

异步从datareader返回数据

[英]Return data from datareader asynchronously

我是异步的东西的新手,并且在尝试让它工作时遇到很多问题:

我试图从SQL加载一个大的结果集我想要发生的是当我运行下面的代码时:

public async override IEnumerable<DataResult> Read()
{
    using (SqlConnection objConn = new SqlConnection(Options.GetConnectionString()))
    {
        await objConn.OpenAsync();
        SqlCommand comm = new SqlCommand(Options.SqlText, objConn);
        SqlDataReader reader = await comm.ExecuteReaderAsync();

        while (await reader.ReadAsync())
            yield return new DataResult { Reader = reader };
    }
}

制片人代码:

BlockingCollection<DataResult> DataCollection = new BlockingCollection<DataResult>();

var producer = new Producer<DataResult>(() =>
{
    using (var sequenceEnum = sourceEngine.Read().GetEnumerator())
    {
        while (sequenceEnum.MoveNext())
            return sequenceEnum.Current;
    }
    return null;
}, DataCollection);
producer.Start();

它返回数据,因为它在逐个记录中将其读取到生产者,生产者将这些数据存储到BlockingCollection以供消费者使用。

我怎样才能让这段代码能够满足我的期望呢?

您的Read签名不是异步的:

public override IEnumerable<DataResult> Read();

此方法的任何实现都必须是同步的。 所以你可以使用yield实现它,而不是使用async / await

如果您希望它是异步的, ReadAsync Read更改为ReadAsync

public override Task<IEnumerable<DataResult>> ReadAsync();

您可以通过(异步)读取列表,然后返回该列表来实现它。

但是,如果您真正想要的是异步序列 (处理每个数据),那么您应该使用Rx:

public override IObservable<DataResult> Read();

您可惜不能yieldasync方法。 将其标记为async ,您需要返回voidTaskTask<T> ,这样可以防止在方法体中yield任何yield

您可以返回IEnumerable<Task<T>> ,返回您之前等待的所有内容,而不是使用await (您将无法在此方法中使用async / await )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM