@@ -2171,45 +2171,45 @@ internal bool TryGetBytesInternalSequential(int i, byte[] buffer, int index, int
2171
2171
{
2172
2172
tdsReliabilitySection . Start ( ) ;
2173
2173
#endif //DEBUG
2174
- if ( ( _sharedState . _columnDataBytesRemaining == 0 ) || ( length == 0 ) )
2175
- {
2176
- // No data left or nothing requested, return 0
2177
- bytesRead = 0 ;
2178
- return true ;
2179
- }
2180
- else
2174
+ if ( ( _sharedState . _columnDataBytesRemaining == 0 ) || ( length == 0 ) )
2175
+ {
2176
+ // No data left or nothing requested, return 0
2177
+ bytesRead = 0 ;
2178
+ return true ;
2179
+ }
2180
+ else
2181
+ {
2182
+ // if plp columns, do partial reads. Don't read the entire value in one shot.
2183
+ if ( _metaData [ i ] . metaType . IsPlp )
2181
2184
{
2182
- // if plp columns, do partial reads. Don't read the entire value in one shot.
2183
- if ( _metaData [ i ] . metaType . IsPlp )
2185
+ // Read in data
2186
+ bool result = _stateObj . TryReadPlpBytes ( ref buffer , index , length , out bytesRead ) ;
2187
+ _columnDataBytesRead += bytesRead ;
2188
+ if ( ! result )
2184
2189
{
2185
- // Read in data
2186
- bool result = _stateObj . TryReadPlpBytes ( ref buffer , index , length , out bytesRead ) ;
2187
- _columnDataBytesRead += bytesRead ;
2188
- if ( ! result )
2189
- {
2190
- return false ;
2191
- }
2192
-
2193
- // Query for number of bytes left
2194
- ulong left ;
2195
- if ( ! _parser . TryPlpBytesLeft ( _stateObj , out left ) )
2196
- {
2197
- _sharedState . _columnDataBytesRemaining = - 1 ;
2198
- return false ;
2199
- }
2200
- _sharedState . _columnDataBytesRemaining = ( long ) left ;
2201
- return true ;
2190
+ return false ;
2202
2191
}
2203
- else
2192
+
2193
+ // Query for number of bytes left
2194
+ ulong left ;
2195
+ if ( ! _parser . TryPlpBytesLeft ( _stateObj , out left ) )
2204
2196
{
2205
- // Read data (not exceeding the total amount of data available)
2206
- int bytesToRead = ( int ) Math . Min ( ( long ) length , _sharedState . _columnDataBytesRemaining ) ;
2207
- bool result = _stateObj . TryReadByteArray ( buffer , index , bytesToRead , out bytesRead ) ;
2208
- _columnDataBytesRead += bytesRead ;
2209
- _sharedState . _columnDataBytesRemaining -= bytesRead ;
2210
- return result ;
2197
+ _sharedState . _columnDataBytesRemaining = - 1 ;
2198
+ return false ;
2211
2199
}
2200
+ _sharedState . _columnDataBytesRemaining = ( long ) left ;
2201
+ return true ;
2212
2202
}
2203
+ else
2204
+ {
2205
+ // Read data (not exceeding the total amount of data available)
2206
+ int bytesToRead = ( int ) Math . Min ( ( long ) length , _sharedState . _columnDataBytesRemaining ) ;
2207
+ bool result = _stateObj . TryReadByteArray ( buffer , index , bytesToRead , out bytesRead ) ;
2208
+ _columnDataBytesRead += bytesRead ;
2209
+ _sharedState . _columnDataBytesRemaining -= bytesRead ;
2210
+ return result ;
2211
+ }
2212
+ }
2213
2213
#if DEBUG
2214
2214
}
2215
2215
finally
@@ -4156,7 +4156,7 @@ private bool TryReadColumnHeader(int i)
4156
4156
{
4157
4157
tdsReliabilitySection . Start ( ) ;
4158
4158
#endif //DEBUG
4159
- return TryReadColumnInternal ( i , readHeaderOnly : true ) ;
4159
+ return TryReadColumnInternal ( i , readHeaderOnly : true ) ;
4160
4160
#if DEBUG
4161
4161
}
4162
4162
finally
@@ -5074,14 +5074,25 @@ private Task<int> GetBytesAsyncReadDataStage(GetBytesAsyncCallContext context, b
5074
5074
SetTimeout ( _defaultTimeoutMilliseconds ) ;
5075
5075
5076
5076
// Try to read without any continuations (all the data may already be in the stateObj's buffer)
5077
- if ( ! TryGetBytesInternalSequential ( context . columnIndex , context . buffer , context . index , context . length , out bytesRead ) )
5077
+ bool filledBuffer = context . _reader . TryGetBytesInternalSequential (
5078
+ context . columnIndex ,
5079
+ context . buffer ,
5080
+ context . index + context . totalBytesRead ,
5081
+ context . length - context . totalBytesRead ,
5082
+ out bytesRead
5083
+ ) ;
5084
+ context . totalBytesRead += bytesRead ;
5085
+ Debug . Assert ( context . totalBytesRead <= context . length , "Read more bytes than required" ) ;
5086
+
5087
+ if ( ! filledBuffer )
5078
5088
{
5079
5089
// This will be the 'state' for the callback
5080
5090
int totalBytesRead = bytesRead ;
5081
5091
5082
5092
if ( ! isContinuation )
5083
5093
{
5084
5094
// This is the first async operation which is happening - setup the _currentTask and timeout
5095
+ Debug . Assert ( context . _source == null , "context._source should not be non-null when trying to change to async" ) ;
5085
5096
source = new TaskCompletionSource < int > ( ) ;
5086
5097
Task original = Interlocked . CompareExchange ( ref _currentTask , source . Task , null ) ;
5087
5098
if ( original != null )
@@ -5090,6 +5101,7 @@ private Task<int> GetBytesAsyncReadDataStage(GetBytesAsyncCallContext context, b
5090
5101
return source . Task ;
5091
5102
}
5092
5103
5104
+ context . _source = source ;
5093
5105
// Check if cancellation due to close is requested (this needs to be done after setting _currentTask)
5094
5106
if ( _cancelAsyncOnCloseToken . IsCancellationRequested )
5095
5107
{
@@ -5118,7 +5130,7 @@ private Task<int> GetBytesAsyncReadDataStage(GetBytesAsyncCallContext context, b
5118
5130
}
5119
5131
else
5120
5132
{
5121
- Debug . Assert ( context . _source != null , "context.source shuld not be null when continuing" ) ;
5133
+ Debug . Assert ( context . _source != null , "context._source shuld not be null when continuing" ) ;
5122
5134
// setup for cleanup\completing
5123
5135
retryTask . ContinueWith (
5124
5136
continuationAction : AAsyncCallContext < int > . s_completeCallback ,
@@ -5177,42 +5189,42 @@ public override Task<bool> ReadAsync(CancellationToken cancellationToken)
5177
5189
{
5178
5190
_stateObj . _shouldHaveEnoughData = true ;
5179
5191
#endif
5180
- if ( _sharedState . _dataReady )
5181
- {
5182
- // Clean off current row
5183
- CleanPartialReadReliable ( ) ;
5184
- }
5192
+ if ( _sharedState . _dataReady )
5193
+ {
5194
+ // Clean off current row
5195
+ CleanPartialReadReliable ( ) ;
5196
+ }
5185
5197
5186
- // If there a ROW token ready (as well as any metadata for the row)
5187
- if ( _stateObj . IsRowTokenReady ( ) )
5188
- {
5189
- // Read the ROW token
5190
- bool result = TryReadInternal ( true , out more ) ;
5191
- Debug . Assert ( result , "Should not have run out of data" ) ;
5198
+ // If there a ROW token ready (as well as any metadata for the row)
5199
+ if ( _stateObj . IsRowTokenReady ( ) )
5200
+ {
5201
+ // Read the ROW token
5202
+ bool result = TryReadInternal ( true , out more ) ;
5203
+ Debug . Assert ( result , "Should not have run out of data" ) ;
5192
5204
5193
- rowTokenRead = true ;
5194
- if ( more )
5205
+ rowTokenRead = true ;
5206
+ if ( more )
5207
+ {
5208
+ // Sequential mode, nothing left to do
5209
+ if ( IsCommandBehavior ( CommandBehavior . SequentialAccess ) )
5195
5210
{
5196
- // Sequential mode, nothing left to do
5197
- if ( IsCommandBehavior ( CommandBehavior . SequentialAccess ) )
5198
- {
5199
- return ADP . TrueTask ;
5200
- }
5201
- // For non-sequential, check if we can read the row data now
5202
- else if ( WillHaveEnoughData ( _metaData . Length - 1 ) )
5203
- {
5204
- // Read row data
5205
- result = TryReadColumn ( _metaData . Length - 1 , setTimeout : true ) ;
5206
- Debug . Assert ( result , "Should not have run out of data" ) ;
5207
- return ADP . TrueTask ;
5208
- }
5211
+ return ADP . TrueTask ;
5209
5212
}
5210
- else
5213
+ // For non-sequential, check if we can read the row data now
5214
+ else if ( WillHaveEnoughData ( _metaData . Length - 1 ) )
5211
5215
{
5212
- // No data left, return
5213
- return ADP . FalseTask ;
5216
+ // Read row data
5217
+ result = TryReadColumn ( _metaData . Length - 1 , setTimeout : true ) ;
5218
+ Debug . Assert ( result , "Should not have run out of data" ) ;
5219
+ return ADP . TrueTask ;
5214
5220
}
5215
5221
}
5222
+ else
5223
+ {
5224
+ // No data left, return
5225
+ return ADP . FalseTask ;
5226
+ }
5227
+ }
5216
5228
#if DEBUG
5217
5229
}
5218
5230
finally
@@ -5373,8 +5385,8 @@ override public Task<bool> IsDBNullAsync(int i, CancellationToken cancellationTo
5373
5385
{
5374
5386
_stateObj . _shouldHaveEnoughData = true ;
5375
5387
#endif
5376
- ReadColumnHeader ( i ) ;
5377
- return _data [ i ] . IsNull ? ADP . TrueTask : ADP . FalseTask ;
5388
+ ReadColumnHeader ( i ) ;
5389
+ return _data [ i ] . IsNull ? ADP . TrueTask : ADP . FalseTask ;
5378
5390
#if DEBUG
5379
5391
}
5380
5392
finally
@@ -5510,7 +5522,7 @@ override public Task<T> GetFieldValueAsync<T>(int i, CancellationToken cancellat
5510
5522
{
5511
5523
_stateObj . _shouldHaveEnoughData = true ;
5512
5524
#endif
5513
- return Task . FromResult ( GetFieldValueInternal < T > ( i ) ) ;
5525
+ return Task . FromResult ( GetFieldValueInternal < T > ( i ) ) ;
5514
5526
#if DEBUG
5515
5527
}
5516
5528
finally
0 commit comments