[英]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();
您可惜不能yield
从async
方法。 将其标记为async
,您需要返回void
, Task
或Task<T>
,这样可以防止在方法体中yield
任何yield
。
您可以返回IEnumerable<Task<T>>
,返回您之前等待的所有内容,而不是使用await
(您将无法在此方法中使用async
/ await
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.