-
Notifications
You must be signed in to change notification settings - Fork 312
Description
When using Microsoft.Data.SqlClient version 6.1.0 in a Blazor app targeting .NET 9.0, SqlDataReader.ReadAsync().ConfigureAwait(false) intermittently stops reading data prematurely (hangs or returns false unexpectedly) without throwing an exception. This occurs after a certain number of records (e.g., 217 out of 218, or 331 out of 332). Downgrading the package to version 6.0.2 resolves the issue.
Environment:
Microsoft.Data.SqlClient Version: 6.1.0 (Problem occurs)
Microsoft.Data.SqlClient Version: 6.0.2 (Problem does not occur)
Visual Studio Version: 17.14.10
Project Type: Blazor App (Server-side)
.NET Framework/Core Version: .NET 9.0
Windows 10/11
SQL Server 2014
Steps to Reproduce:
Create a Blazor Server application targeting .NET 9.0.
Install Microsoft.Data.SqlClient version 6.1.0.
Implement an asynchronous method to read a relatively large number of records (e.g., 30,000) from a SQL Server database using SqlDataReader. Ensure the query returns more than a few hundred rows.
In the loop, use while (await sreader.ReadAsync().ConfigureAwait(false)).
Example code snippet (simplified):
private async Task ProcessRecordsAsync()
{
string connectionString = "YourConnectionStringHere";
string commandText = "SELECT YourXmlColumn FROM YourTable WHERE ... ORDER BY ..."; // Query returning many rows, including XML data
using (SqlConnection connection = new(connectionString))
{
using (SqlCommand command = new(commandText, connection))
{
command.CommandTimeout = 800; // High timeout
await connection.OpenAsync().ConfigureAwait(false);
using (SqlDataReader sreader = await command.ExecuteReaderAsync().ConfigureAwait(false))
{
int i = 0;
while (await sreader.ReadAsync().ConfigureAwait(false))
{
i++;
Console.WriteLine($"Processing record {i}");
// string xmlData = sreader.GetString(0); // If actually reading data
// Perform some minimal operation, or just let it loop
}
Console.WriteLine($"Loop finished. Total records processed: {i}"); // This line is often not reached
}
}
}
}
Call this method from a Blazor component's lifecycle method (e.g., OnInitializedAsync()) or an event handler.
Expected Behavior:
The while (await sreader.ReadAsync().ConfigureAwait(false)) loop should iterate through all available records (e.g., 218 or 332 records) and complete normally.
Actual Behavior:
The while (await sreader.ReadAsync().ConfigureAwait(false)) loop stops prematurely (e.g., after 217 or 331 records), without reaching the total number of records returned by the query. No exception is thrown (e.g., ObjectDisposedException or SqlException), and the code execution simply appears to halt within the ReadAsync() call for the subsequent record.
Additional Information:
When using the synchronous method sreader.Read() instead of await sreader.ReadAsync(), the loop completes successfully and processes all records. This suggests the issue is specific to the asynchronous implementation in Microsoft.Data.SqlClient 6.1.0.
SqlDataAdapter.Fill(DataTable) also successfully retrieves all records, confirming that the database query and connection are fundamentally sound and all data is available.
The issue persists even when Pooling=false is added to the connection string.
The problem specifically occurs with Microsoft.Data.SqlClient version 6.1.0. Reverting to version 6.0.2 resolves the issue completely.