Files
xDataService/Mongo/XAsyncEnumerableAdapter.cs
2024-01-25 04:41:17 +03:30

73 lines
2.2 KiB
C#

using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using MongoDB.Driver;
namespace xDataService.Mongo {
public class XAsyncEnumerableAdapter<T> : IAsyncEnumerable<T> {
//
private readonly IAsyncCursorSource<T> asyncCursorSource;
//
public XAsyncEnumerableAdapter (IAsyncCursorSource<T> asyncCursorSource) {
this.asyncCursorSource = asyncCursorSource;
}
//
public IAsyncEnumerator<T> GetAsyncEnumerator (CancellationToken cancellationToken) =>
new XAsyncEnumeratorAdapter<T> (asyncCursorSource, cancellationToken);
}
public class XAsyncEnumeratorAdapter<T> : IAsyncEnumerator<T> {
private readonly IAsyncCursorSource<T> asyncCursorSource;
private readonly CancellationToken cancellationToken;
private IAsyncCursor<T> asyncCursor;
private IEnumerator<T> batchEnumerator;
public T Current => batchEnumerator.Current;
public XAsyncEnumeratorAdapter (
IAsyncCursorSource<T> asyncCursorSource,
CancellationToken cancellationToken
) {
//
this.asyncCursorSource = asyncCursorSource;
this.cancellationToken = cancellationToken;
}
public async ValueTask<bool> MoveNextAsync () {
//
if (asyncCursor == null) {
asyncCursor = await asyncCursorSource
.ToCursorAsync (cancellationToken);
}
//
if (batchEnumerator != null &&
batchEnumerator.MoveNext ()) {
return true;
}
//
if (asyncCursor != null &&
await asyncCursor.MoveNextAsync (cancellationToken)) {
//
batchEnumerator?.Dispose ();
batchEnumerator = asyncCursor.Current.GetEnumerator ();
//
return batchEnumerator.MoveNext ();
}
//
return false;
}
public async ValueTask DisposeAsync () {
//
await Task.CompletedTask;
asyncCursor?.Dispose ();
asyncCursor = null;
}
}
}