Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
07-07-2020 06:39 AM
I am using the new Async driver and was wondering how to use it in conjunction with IAsyncEnumerable. Let's say I have 1million nodes and I want to stream them node by node, so it can be consumed by another methodA whenever this methodA is ready.
public async IAsyncEnumerable<IRecord> GetRecords()
{
var session = _neo4J.Driver.AsyncSession(o => o.WithDatabase("neo4j"));
try
{
var cursor = await session.RunAsync(
@"match (node:SomeNode)
return node");
//somehow yield return the records here?
}
catch (Exception e)
{
var error = e.ToString();
}
finally
{
await session.CloseAsync();
}
}
private void MethodA()
{
await foreach (var record in GetRecords())
{
// do something
}
}
What's the correct way to do this? Are there any async examples for the new 4.0 driver? What happens when the database nodes change while the execution is still in the for each loop?
Solved! Go to Solution.
07-07-2020 07:16 AM
Hello!
Welcome to the community 🙂
You would yield return
the content of the .Current
property:
public static async IAsyncEnumerable<IRecord> GetRecords(IDriver driver)
{
var session = driver.AsyncSession(o => o.WithDatabase("neo4j"));
try
{
var cursor = await session.RunAsync("MATCH (node:Movie) RETURN node ORDER BY node.title");
while(await cursor.FetchAsync()){
yield return cursor.Current;
}
}
finally
{
await session.CloseAsync();
}
}
FetchAsync()
method will return true
while there is still data in the stream, false
when it's ended.cursor.Current
contains the current value, which you'll want to yield
.catch(Exception e)
code block has been removed, as you can't do a yield return
within a try/catch
.If the nodes change whilst you're in the loop you will get the old version, for example, if you were streaming a list of Movies ordered by their Title, if someone was to change Cast Away
to Cast Back
you would still see Cast Away
in your output.
One thing you might also want to consider is the Reactive Extensions version, which would give MethodA
even more control over what it receives. I wrote a short post about that here: https://xclave.co.uk/2019/11/27/reactive-neo4j-using-net/
All the best
Chris
07-07-2020 07:16 AM
Hello!
Welcome to the community 🙂
You would yield return
the content of the .Current
property:
public static async IAsyncEnumerable<IRecord> GetRecords(IDriver driver)
{
var session = driver.AsyncSession(o => o.WithDatabase("neo4j"));
try
{
var cursor = await session.RunAsync("MATCH (node:Movie) RETURN node ORDER BY node.title");
while(await cursor.FetchAsync()){
yield return cursor.Current;
}
}
finally
{
await session.CloseAsync();
}
}
FetchAsync()
method will return true
while there is still data in the stream, false
when it's ended.cursor.Current
contains the current value, which you'll want to yield
.catch(Exception e)
code block has been removed, as you can't do a yield return
within a try/catch
.If the nodes change whilst you're in the loop you will get the old version, for example, if you were streaming a list of Movies ordered by their Title, if someone was to change Cast Away
to Cast Back
you would still see Cast Away
in your output.
One thing you might also want to consider is the Reactive Extensions version, which would give MethodA
even more control over what it receives. I wrote a short post about that here: https://xclave.co.uk/2019/11/27/reactive-neo4j-using-net/
All the best
Chris
All the sessions of the conference are now available online