@@ -432,21 +432,19 @@ int IElementOperations.GetCollectionCount(object collection, out int[]? lengths)
432432 Size ? IElementOperations . GetSizeOrDbNull ( SizeContext context , object collection , int [ ] indices , ref object ? writeState )
433433 => _elemConverter . GetSizeOrDbNull ( context . Format , context . BufferRequirement , GetValue ( collection , indices ) , ref writeState ) ;
434434
435- unsafe ValueTask IElementOperations . Read ( bool async , PgReader reader , bool isDbNull , object collection , int [ ] indices , CancellationToken cancellationToken )
435+ ValueTask IElementOperations . Read ( bool async , PgReader reader , bool isDbNull , object collection , int [ ] indices , CancellationToken cancellationToken )
436436 {
437- TElement ? result ;
438- if ( isDbNull )
439- result = default ;
440- else if ( ! async )
441- result = _elemConverter . Read ( reader ) ;
442- else
443- {
444- var task = _elemConverter . ReadAsync ( reader , cancellationToken ) ;
445- if ( ! task . IsCompletedSuccessfully )
446- return AwaitTask ( task . AsTask ( ) , new ( this , & SetResult ) , collection , indices ) ;
437+ if ( ! isDbNull && async & & _elemConverter is PgStreamingConverter < TElement > streamingConverter )
438+ return ReadAsync ( streamingConverter , reader , collection , indices , cancellationToken ) ;
447439
448- result = task . Result ;
449- }
440+ SetValue ( collection , indices , isDbNull ? default : _elemConverter . Read ( reader ) ) ;
441+ return new ( ) ;
442+ }
443+
444+ unsafe ValueTask ReadAsync ( PgStreamingConverter < TElement > converter , PgReader reader , object collection , int [ ] indices , CancellationToken cancellationToken )
445+ {
446+ if ( converter . ReadAsyncAsTask ( reader , cancellationToken , out var result ) is { } task )
447+ return AwaitTask ( task , new ( this , & SetResult ) , collection , indices ) ;
450448
451449 SetValue ( collection , indices , result ) ;
452450 return new ( ) ;
@@ -505,34 +503,32 @@ int IElementOperations.GetCollectionCount(object collection, out int[]? lengths)
505503 Size? IElementOperations . GetSizeOrDbNull ( SizeContext context , object collection , int [ ] indices , ref object ? writeState )
506504 => _elemConverter . GetSizeOrDbNull ( context . Format , context . BufferRequirement , GetValue ( collection , indices [ 0 ] ) , ref writeState ) ;
507505
508- unsafe ValueTask IElementOperations. Read ( bool async , PgReader reader , bool isDbNull , object collection , int [ ] indices , CancellationToken cancellationToken )
506+ ValueTask IElementOperations. Read ( bool async , PgReader reader , bool isDbNull , object collection , int [ ] indices , CancellationToken cancellationToken )
509507 {
510508 Debug. Assert ( indices . Length is 1 ) ;
511- TElement? result ;
512- if ( isDbNull )
513- result = default ;
514- else if ( ! async )
515- result = _elemConverter. Read ( reader ) ;
516- else
517- {
518- var task = _elemConverter. ReadAsync( reader , cancellationToken ) ;
519- if ( ! task . IsCompletedSuccessfully )
520- return AwaitTask ( task . AsTask ( ) , new ( this , & SetResult ) , collection , indices ) ;
509+ if ( ! isDbNull && async & & _elemConverter is PgStreamingConverter < TElement > streamingConverter )
510+ return ReadAsync( streamingConverter , reader , collection , indices , cancellationToken ) ;
521511
522- result = task . Result ;
523- }
524-
525- SetValue( collection , indices [ 0 ] , result ) ;
512+ SetValue( collection , indices [ 0 ] , isDbNull ? default : _elemConverter . Read ( reader ) ) ;
526513 return new ( ) ;
527-
528- // Using .Result on ValueTask is equivalent to GetAwaiter().GetResult(), this removes TaskAwaiter<TElement> rooting.
529- static void SetResult ( Task task , object collection , int [ ] indices )
530- {
531- Debug . Assert ( task is Task < TElement > ) ;
532- SetValue( collection , indices [ 0 ] , new ValueTask < TElement > ( Unsafe . As < Task < TElement > > ( task ) ) . Result ) ;
533- }
534514 }
535515
516+ unsafe ValueTask ReadAsync( PgStreamingConverter < TElement > converter , PgReader reader , object collection , int [ ] indices , CancellationToken cancellationToken )
517+ {
518+ if ( converter . ReadAsyncAsTask ( reader , cancellationToken , out var result ) is { } task )
519+ return AwaitTask( task , new ( this , & SetResult ) , collection , indices ) ;
520+
521+ SetValue( collection , indices [ 0 ] , result ) ;
522+ return new ( ) ;
523+
524+ // Using .Result on ValueTask is equivalent to GetAwaiter().GetResult(), this removes TaskAwaiter<TElement> rooting.
525+ static void SetResult( Task task , object collection , int [ ] indices )
526+ {
527+ Debug. Assert ( task is Task < TElement > ) ;
528+ SetValue( collection , indices [ 0 ] , new ValueTask < TElement > ( Unsafe . As < Task < TElement > > ( task ) ) . Result ) ;
529+ }
530+ }
531+
536532 ValueTask IElementOperations. Write ( bool async , PgWriter writer , object collection , int [ ] indices , CancellationToken cancellationToken )
537533 {
538534 Debug. Assert ( indices . Length is 1 ) ;
0 commit comments