From 6099746922f8637d0c05dc0d153a3fe3e3784f10 Mon Sep 17 00:00:00 2001
From: Cheena Malhotra <13396919+cheenamalhotra@users.noreply.github.com>
Date: Wed, 2 Aug 2023 14:04:30 -0700
Subject: [PATCH] Improve Query editor Read performance + cancel timely for
large data (#2161)
---
.../QueryExecution/Batch.cs | 1 +
.../DataStorage/StorageDataReader.cs | 22 +++++++++++++++++++
.../QueryExecution/ResultSet.cs | 3 ++-
3 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/Batch.cs b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/Batch.cs
index 28126227..c96b6ad8 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/Batch.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/Batch.cs
@@ -429,6 +429,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
{
do
{
+ cancellationToken.ThrowIfCancellationRequested();
columnSchemas.Add(reader.GetColumnSchema().ToArray());
} while (reader.NextResult());
}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/StorageDataReader.cs b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/StorageDataReader.cs
index 49209154..dc8de79e 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/StorageDataReader.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/StorageDataReader.cs
@@ -88,11 +88,33 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
///
/// The cancellation token to use for cancelling a query
///
+ [Obsolete("Deprecated due to performance issues, please use Read() instead.")]
public Task ReadAsync(CancellationToken cancellationToken)
{
return DbDataReader.ReadAsync(cancellationToken);
}
+ ///
+ /// Pass-through to DbDataReader.Read()
+ ///
+ /// ************** IMPORTANT ****************
+ /// M.D.SqlClient's ReadAsync() implementation is not as
+ /// performant as Read() and doesn't respect Cancellation Token
+ /// due to long existing design issues like below:
+ ///
+ /// https://github.com/dotnet/SqlClient/issues/593
+ /// https://github.com/dotnet/SqlClient/issues/44
+ ///
+ /// Until these issues are resolved, prefer using Sync APIs.
+ /// *****************************************
+ ///
+ ///
+ ///
+ public bool Read()
+ {
+ return DbDataReader.Read();
+ }
+
///
/// Retrieves a value
///
diff --git a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/ResultSet.cs b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/ResultSet.cs
index 1487114d..19406c85 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/ResultSet.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/ResultSet.cs
@@ -396,8 +396,9 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
//
availableTask = SendCurrentResults();
- while (await dataReader.ReadAsync(cancellationToken))
+ while (dataReader.Read())
{
+ cancellationToken.ThrowIfCancellationRequested();
fileOffsets.Add(totalBytesWritten);
totalBytesWritten += fileWriter.WriteRow(dataReader);
}