From a8a269d24db49bc7ffd933009fb890a307e371d3 Mon Sep 17 00:00:00 2001 From: Alexey Kulakov Date: Thu, 24 Sep 2020 23:12:49 +0500 Subject: [PATCH 1/2] Makes QueryCommand implement IAsyncDisposable --- .../Internals/BulkDeleteOperation.cs | 8 ++++---- .../Internals/BulkUpdateOperation.cs | 10 +++++----- .../Internals/InsertOperation.cs | 8 ++++---- .../Orm/Services/QueryBuilding/QueryCommand.cs | 14 +++++++++++++- 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/Extensions/Xtensive.Orm.BulkOperations/Internals/BulkDeleteOperation.cs b/Extensions/Xtensive.Orm.BulkOperations/Internals/BulkDeleteOperation.cs index d447c05a5c..131a815257 100644 --- a/Extensions/Xtensive.Orm.BulkOperations/Internals/BulkDeleteOperation.cs +++ b/Extensions/Xtensive.Orm.BulkOperations/Internals/BulkDeleteOperation.cs @@ -34,19 +34,19 @@ protected override int ExecuteInternal() return command.ExecuteNonQuery(); } - protected override Task ExecuteInternalAsync(CancellationToken token = default) + protected async override Task ExecuteInternalAsync(CancellationToken token = default) { if (PrimaryIndexes.Length > 1) { throw new NotImplementedException("Inheritance is not implemented"); } - base.ExecuteInternal(); + _ = base.ExecuteInternal(); var request = GetRequest(query); Bindings = request.ParameterBindings.ToList(); - var command = CreateCommand(request); - return command.ExecuteNonQueryAsync(token); + await using var command = CreateCommand(request); + return await command.ExecuteNonQueryAsync(token).ConfigureAwait(false); } private QueryCommand CreateCommand(QueryTranslationResult request) diff --git a/Extensions/Xtensive.Orm.BulkOperations/Internals/BulkUpdateOperation.cs b/Extensions/Xtensive.Orm.BulkOperations/Internals/BulkUpdateOperation.cs index ae03b8e01f..f1582a0e55 100644 --- a/Extensions/Xtensive.Orm.BulkOperations/Internals/BulkUpdateOperation.cs +++ b/Extensions/Xtensive.Orm.BulkOperations/Internals/BulkUpdateOperation.cs @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2020 Xtensive LLC. +// Copyright (C) 2019-2020 Xtensive LLC. // This code is distributed under MIT license terms. // See the License.txt file in the project root for more information. @@ -38,18 +38,18 @@ protected override int ExecuteInternal() return command.ExecuteNonQuery(); } - protected override Task ExecuteInternalAsync(CancellationToken token = default) + protected async override Task ExecuteInternalAsync(CancellationToken token = default) { if (PrimaryIndexes.Length > 1) { throw new NotImplementedException("Inheritance is not implemented"); } - base.ExecuteInternal(); + _ = base.ExecuteInternal(); var request = GetRequest(query); Bindings = request.ParameterBindings.ToList(); - var command = CreateCommand(request); - return command.ExecuteNonQueryAsync(token); + await using var command = CreateCommand(request); + return await command.ExecuteNonQueryAsync(token).ConfigureAwait(false); } private QueryCommand CreateCommand(QueryTranslationResult request) diff --git a/Extensions/Xtensive.Orm.BulkOperations/Internals/InsertOperation.cs b/Extensions/Xtensive.Orm.BulkOperations/Internals/InsertOperation.cs index 51c667ccc2..73a0117ad2 100644 --- a/Extensions/Xtensive.Orm.BulkOperations/Internals/InsertOperation.cs +++ b/Extensions/Xtensive.Orm.BulkOperations/Internals/InsertOperation.cs @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2020 Xtensive LLC. +// Copyright (C) 2019-2020 Xtensive LLC. // This code is distributed under MIT license terms. // See the License.txt file in the project root for more information. @@ -32,15 +32,15 @@ protected override int ExecuteInternal() return command.ExecuteNonQuery(); } - protected override Task ExecuteInternalAsync(CancellationToken token = default) + protected async override Task ExecuteInternalAsync(CancellationToken token = default) { if (PrimaryIndexes.Length > 1) { throw new NotImplementedException("Inheritance is not implemented"); } Bindings = new List(); - var command = CreateCommand(); - return command.ExecuteNonQueryAsync(token); + await using var command = CreateCommand(); + return await command.ExecuteNonQueryAsync(token).ConfigureAwait(false); } private QueryCommand CreateCommand() diff --git a/Orm/Xtensive.Orm/Orm/Services/QueryBuilding/QueryCommand.cs b/Orm/Xtensive.Orm/Orm/Services/QueryBuilding/QueryCommand.cs index 1307174051..3d8fcd2d61 100644 --- a/Orm/Xtensive.Orm/Orm/Services/QueryBuilding/QueryCommand.cs +++ b/Orm/Xtensive.Orm/Orm/Services/QueryBuilding/QueryCommand.cs @@ -18,7 +18,7 @@ namespace Xtensive.Orm.Services /// Unlike this type is aware of /// and does all necessary logging of executed SQL. /// - public sealed class QueryCommand : IDisposable + public sealed class QueryCommand : IDisposable, IAsyncDisposable { private readonly StorageDriver driver; private readonly Session session; @@ -117,6 +117,18 @@ public void Dispose() realCommand?.Dispose(); } + public ValueTask DisposeAsync() + { + if (disposed) { + return default; + } + disposed = true; + if (realCommand != null) { + return realCommand.DisposeAsync(); + } + return default; + } + // Constructors internal QueryCommand(StorageDriver driver, Session session, DbCommand realCommand) From 30de860ddd2bc507e043c13e258ba65a2005ca49 Mon Sep 17 00:00:00 2001 From: Alexey Kulakov Date: Fri, 25 Sep 2020 11:04:29 +0500 Subject: [PATCH 2/2] Applies .ConfigureAwait(false) for QueryCommand in await using --- .../Internals/BulkDeleteOperation.cs | 6 ++++-- .../Internals/BulkUpdateOperation.cs | 6 ++++-- .../Internals/InsertOperation.cs | 6 ++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Extensions/Xtensive.Orm.BulkOperations/Internals/BulkDeleteOperation.cs b/Extensions/Xtensive.Orm.BulkOperations/Internals/BulkDeleteOperation.cs index 131a815257..711751e6fb 100644 --- a/Extensions/Xtensive.Orm.BulkOperations/Internals/BulkDeleteOperation.cs +++ b/Extensions/Xtensive.Orm.BulkOperations/Internals/BulkDeleteOperation.cs @@ -45,8 +45,10 @@ protected async override Task ExecuteInternalAsync(CancellationToken token var request = GetRequest(query); Bindings = request.ParameterBindings.ToList(); - await using var command = CreateCommand(request); - return await command.ExecuteNonQueryAsync(token).ConfigureAwait(false); + var command = CreateCommand(request); + await using (command.ConfigureAwait(false)) { + return await command.ExecuteNonQueryAsync(token).ConfigureAwait(false); + } } private QueryCommand CreateCommand(QueryTranslationResult request) diff --git a/Extensions/Xtensive.Orm.BulkOperations/Internals/BulkUpdateOperation.cs b/Extensions/Xtensive.Orm.BulkOperations/Internals/BulkUpdateOperation.cs index f1582a0e55..da6d5e83ea 100644 --- a/Extensions/Xtensive.Orm.BulkOperations/Internals/BulkUpdateOperation.cs +++ b/Extensions/Xtensive.Orm.BulkOperations/Internals/BulkUpdateOperation.cs @@ -48,8 +48,10 @@ protected async override Task ExecuteInternalAsync(CancellationToken token var request = GetRequest(query); Bindings = request.ParameterBindings.ToList(); - await using var command = CreateCommand(request); - return await command.ExecuteNonQueryAsync(token).ConfigureAwait(false); + var command = CreateCommand(request); + await using (command.ConfigureAwait(false)) { + return await command.ExecuteNonQueryAsync(token).ConfigureAwait(false); + } } private QueryCommand CreateCommand(QueryTranslationResult request) diff --git a/Extensions/Xtensive.Orm.BulkOperations/Internals/InsertOperation.cs b/Extensions/Xtensive.Orm.BulkOperations/Internals/InsertOperation.cs index 73a0117ad2..394ef317b8 100644 --- a/Extensions/Xtensive.Orm.BulkOperations/Internals/InsertOperation.cs +++ b/Extensions/Xtensive.Orm.BulkOperations/Internals/InsertOperation.cs @@ -39,8 +39,10 @@ protected async override Task ExecuteInternalAsync(CancellationToken token } Bindings = new List(); - await using var command = CreateCommand(); - return await command.ExecuteNonQueryAsync(token).ConfigureAwait(false); + var command = CreateCommand(); + await using (command.ConfigureAwait(false)) { + return await command.ExecuteNonQueryAsync(token).ConfigureAwait(false); + } } private QueryCommand CreateCommand()