Return data from datareader asynchronously
I'm new to asynchronous stuff and I'm having a lot of problems trying to get this to work:
I am trying to load a large result set from SQL, which is what I want when I run the code below:
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 };
}
}
Manufacturer Code:
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();
That it returns data when it writes it to the record by record to the producer, who will store that data in BlockingCollection
for consumption by the consumer.
How can I get this code to work for what I expect from it?
source to share
Your signature is Read
not asynchronous:
public override IEnumerable<DataResult> Read();
Any implementation of this method must be synchronous. So you can only implement it with yield
and not use async
/ await
at all.
If you want it to be asynchronous, change Read
to ReadAsync
:
public override Task<IEnumerable<DataResult>> ReadAsync();
which you can implement (asynchronously) on a list and then return that list.
However, if what you really want is an asynchronous sequence (processing each piece of data as it comes in), then you should use Rx:
public override IObservable<DataResult> Read();
source to share
You, unfortunately, cannot yield
from the method async
. By marking it as async
, you need to return void
, Task
or Task<T>
and this will prevent yield
the method from being created in the body.
You might come back IEnumerable<Task<T>>
by returning whatever you previously expected instead of using await
(you won't be able to use async
/ await
in this method anymore ).
source to share