diff --git a/eng/Packages.Data.props b/eng/Packages.Data.props index e34727aa5562..bbc47083a99c 100644 --- a/eng/Packages.Data.props +++ b/eng/Packages.Data.props @@ -11,8 +11,8 @@ - - + + diff --git a/sdk/core/Azure.Core/src/Shared/TaskExtensions.cs b/sdk/core/Azure.Core/src/Shared/TaskExtensions.cs index 61b215054ec0..a22738192f8b 100644 --- a/sdk/core/Azure.Core/src/Shared/TaskExtensions.cs +++ b/sdk/core/Azure.Core/src/Shared/TaskExtensions.cs @@ -25,11 +25,6 @@ public static T EnsureCompleted(this Task task) { #if DEBUG VerifyTaskCompleted(task.IsCompleted); -#else - if (HasSynchronizationContext()) - { - throw new InvalidOperationException("Synchronously waiting on non-completed task isn't allowed."); - } #endif #pragma warning disable AZC0102 // Do not use GetAwaiter().GetResult(). Use the TaskExtensions.EnsureCompleted() extension method instead. return task.GetAwaiter().GetResult(); @@ -40,11 +35,6 @@ public static void EnsureCompleted(this Task task) { #if DEBUG VerifyTaskCompleted(task.IsCompleted); -#else - if (HasSynchronizationContext()) - { - throw new InvalidOperationException("Synchronously waiting on non-completed task isn't allowed."); - } #endif #pragma warning disable AZC0102 // Do not use GetAwaiter().GetResult(). Use the TaskExtensions.EnsureCompleted() extension method instead. task.GetAwaiter().GetResult(); @@ -53,12 +43,9 @@ public static void EnsureCompleted(this Task task) public static T EnsureCompleted(this ValueTask task) { - if (!task.IsCompleted) - { -#pragma warning disable AZC0107 // public asynchronous method shouldn't be called in synchronous scope. Use synchronous version of the method if it is available. - return EnsureCompleted(task.AsTask()); -#pragma warning restore AZC0107 // public asynchronous method shouldn't be called in synchronous scope. Use synchronous version of the method if it is available. - } +#if DEBUG + VerifyTaskCompleted(task.IsCompleted); +#endif #pragma warning disable AZC0102 // Do not use GetAwaiter().GetResult(). Use the TaskExtensions.EnsureCompleted() extension method instead. return task.GetAwaiter().GetResult(); #pragma warning restore AZC0102 // Do not use GetAwaiter().GetResult(). Use the TaskExtensions.EnsureCompleted() extension method instead. @@ -66,18 +53,12 @@ public static T EnsureCompleted(this ValueTask task) public static void EnsureCompleted(this ValueTask task) { - if (!task.IsCompleted) - { -#pragma warning disable AZC0107 // public asynchronous method shouldn't be called in synchronous scope. Use synchronous version of the method if it is available. - EnsureCompleted(task.AsTask()); -#pragma warning restore AZC0107 // public asynchronous method shouldn't be called in synchronous scope. Use synchronous version of the method if it is available. - } - else - { +#if DEBUG + VerifyTaskCompleted(task.IsCompleted); +#endif #pragma warning disable AZC0102 // Do not use GetAwaiter().GetResult(). Use the TaskExtensions.EnsureCompleted() extension method instead. - task.GetAwaiter().GetResult(); + task.GetAwaiter().GetResult(); #pragma warning restore AZC0102 // Do not use GetAwaiter().GetResult(). Use the TaskExtensions.EnsureCompleted() extension method instead. - } } public static Enumerable EnsureSyncEnumerable(this IAsyncEnumerable asyncEnumerable) => new Enumerable(asyncEnumerable); @@ -120,9 +101,6 @@ private static void VerifyTaskCompleted(bool isCompleted) } } - private static bool HasSynchronizationContext() - => SynchronizationContext.Current != null && SynchronizationContext.Current.GetType() != typeof(SynchronizationContext) || TaskScheduler.Current != TaskScheduler.Default; - /// /// Both and are defined as public structs so that foreach can use duck typing /// to call and avoid heap memory allocation. diff --git a/sdk/core/Azure.Core/tests/TaskExtensionsTest.cs b/sdk/core/Azure.Core/tests/TaskExtensionsTest.cs index 9fe2dd399949..4ce2839ef361 100644 --- a/sdk/core/Azure.Core/tests/TaskExtensionsTest.cs +++ b/sdk/core/Azure.Core/tests/TaskExtensionsTest.cs @@ -4,7 +4,6 @@ using Azure.Core.Pipeline; using NUnit.Framework; using System; -using System.Collections.Concurrent; using System.Threading; using System.Threading.Tasks; @@ -12,136 +11,6 @@ namespace Azure.Core.Tests { public class TaskExtensionsTest { - [Test] - public void TaskExtensions_TaskEnsureCompleted() - { - var task = Task.CompletedTask; - task.EnsureCompleted(); - } - - [Test] - public void TaskExtensions_TaskOfTEnsureCompleted() - { - var task = Task.FromResult(42); - Assert.AreEqual(42, task.EnsureCompleted()); - } - - [Test] - public void TaskExtensions_ValueTaskEnsureCompleted() - { - var task = new ValueTask(); - task.EnsureCompleted(); - } - - [Test] - public void TaskExtensions_ValueTaskOfTEnsureCompleted() - { - var task = new ValueTask(42); - Assert.AreEqual(42, task.EnsureCompleted()); - } - - [Test] - public async Task TaskExtensions_TaskEnsureCompleted_NotCompletedNoSyncContext() - { - var tcs = new TaskCompletionSource(); - Task task = tcs.Task; -#if DEBUG - Assert.Catch(() => task.EnsureCompleted()); - await Task.CompletedTask; -#else - Task runningTask = Task.Run(() => task.EnsureCompleted()); - Assert.IsFalse(runningTask.IsCompleted); - tcs.SetResult(0); - await runningTask; -#endif - } - - [Test] - public async Task TaskExtensions_TaskOfTEnsureCompleted_NotCompletedNoSyncContext() - { - var tcs = new TaskCompletionSource(); -#if DEBUG - Assert.Catch(() => tcs.Task.EnsureCompleted()); - await Task.CompletedTask; -#else - Task runningTask = Task.Run(() => tcs.Task.EnsureCompleted()); - Assert.IsFalse(runningTask.IsCompleted); - tcs.SetResult(42); - Assert.AreEqual(42, await runningTask); -#endif - } - - [Test] - public async Task TaskExtensions_ValueTaskEnsureCompleted_NotCompletedNoSyncContext() - { - var tcs = new TaskCompletionSource(); - ValueTask task = new ValueTask(tcs.Task); -#if DEBUG - Assert.Catch(() => task.EnsureCompleted()); - await Task.CompletedTask; -#else - Task runningTask = Task.Run(() => task.EnsureCompleted()); - Assert.IsFalse(runningTask.IsCompleted); - tcs.SetResult(0); - await runningTask; -#endif - } - - [Test] - public async Task TaskExtensions_ValueTaskOfTEnsureCompleted_NotCompletedNoSyncContext() - { - var tcs = new TaskCompletionSource(); - ValueTask task = new ValueTask(tcs.Task); -#if DEBUG - Assert.Catch(() => task.EnsureCompleted()); - await Task.CompletedTask; -#else - Task runningTask = Task.Run(() => task.EnsureCompleted()); - Assert.IsFalse(runningTask.IsCompleted); - tcs.SetResult(42); - Assert.AreEqual(42, await runningTask); -#endif - } - - [Test] - public void TaskExtensions_TaskEnsureCompleted_NotCompletedInSyncContext() - { - using SingleThreadedSynchronizationContext syncContext = new SingleThreadedSynchronizationContext(); - var tcs = new TaskCompletionSource(); - Task task = tcs.Task; - - syncContext.Post(t => { Assert.Catch(() => task.EnsureCompleted()); }, null); - } - - [Test] - public void TaskExtensions_TaskOfTEnsureCompleted_NotCompletedInSyncContext() - { - using SingleThreadedSynchronizationContext syncContext = new SingleThreadedSynchronizationContext(); - var tcs = new TaskCompletionSource(); - - syncContext.Post(t => { Assert.Catch(() => tcs.Task.EnsureCompleted()); }, null); - } - - [Test] - public void TaskExtensions_ValueTaskEnsureCompleted_NotCompletedInSyncContext() - { - using SingleThreadedSynchronizationContext syncContext = new SingleThreadedSynchronizationContext(); - var tcs = new TaskCompletionSource(); - ValueTask task = new ValueTask(tcs.Task); - - syncContext.Post(t => { Assert.Catch(() => task.EnsureCompleted()); }, null); - } - - [Test] - public void TaskExtensions_ValueTaskOfTEnsureCompleted_NotCompletedInSyncContext() - { - using SingleThreadedSynchronizationContext syncContext = new SingleThreadedSynchronizationContext(); - var tcs = new TaskCompletionSource(); - var task = new ValueTask(tcs.Task); - - syncContext.Post(t => { Assert.Catch(() => task.EnsureCompleted()); }, null); - } - [Test] public void TaskExtensions_TaskWithCancellationDefault() { @@ -323,55 +192,5 @@ public void TaskExtensions_ValueTaskWithCancellationFailedAfterContinuationSched Assert.AreEqual(true, awaiter.IsCompleted); Assert.Catch(() => awaiter.GetResult(), "Error"); } - - private sealed class SingleThreadedSynchronizationContext : SynchronizationContext, IDisposable - { - private readonly Task _task; - private readonly BlockingCollection _queue; - private readonly ConcurrentQueue _exceptions; - - public SingleThreadedSynchronizationContext() - { - _queue = new BlockingCollection(); - _exceptions = new ConcurrentQueue(); - _task = Task.Run(RunLoop); - } - - private void RunLoop() - { - try - { - SetSynchronizationContext(this); - while (!_queue.IsCompleted) - { - Action action = _queue.Take(); - try - { - action(); - } - catch (Exception e) - { - _exceptions.Enqueue(e); - } - } - } - catch (InvalidOperationException) { } - catch (OperationCanceledException) { } - finally - { - SetSynchronizationContext(null); - } - } - - public override void Post(SendOrPostCallback d, object state) => _queue.Add(() => d(state)); - - public void Dispose() - { - _queue.CompleteAdding(); - _task.Wait(); - } - - public AggregateException Exceptions => new AggregateException(_exceptions); - } } } diff --git a/sdk/storage/Azure.Storage.Blobs.Batch/CHANGELOG.md b/sdk/storage/Azure.Storage.Blobs.Batch/CHANGELOG.md index 6e34966de46a..c61fd6b788f0 100644 --- a/sdk/storage/Azure.Storage.Blobs.Batch/CHANGELOG.md +++ b/sdk/storage/Azure.Storage.Blobs.Batch/CHANGELOG.md @@ -1,5 +1,8 @@ # Release History +## 12.3.1 (2020-08-18) +- Bug in TaskExtensions.EnsureCompleted method that causes it to unconditionally throw an exception in the environments with synchronization context + ## 12.3.0 (2020-08-13) - This release contains bug fixes to improve quality. diff --git a/sdk/storage/Azure.Storage.Blobs.Batch/src/Azure.Storage.Blobs.Batch.csproj b/sdk/storage/Azure.Storage.Blobs.Batch/src/Azure.Storage.Blobs.Batch.csproj index 5c1bfb9ce13f..9d94d1efff2b 100644 --- a/sdk/storage/Azure.Storage.Blobs.Batch/src/Azure.Storage.Blobs.Batch.csproj +++ b/sdk/storage/Azure.Storage.Blobs.Batch/src/Azure.Storage.Blobs.Batch.csproj @@ -4,7 +4,7 @@ Microsoft Azure.Storage.Blobs.Batch client library - 12.3.0 + 12.3.1 12.2.1 BlobSDK;$(DefineConstants) Microsoft Azure Storage Blobs Batching;Batch blob;Batch operation;BlobBatchClient;BlobBatch;Microsoft;Azure;Blobs;Blob;Storage;StorageScalable;$(PackageCommonTags) diff --git a/sdk/storage/Azure.Storage.Blobs.ChangeFeed/CHANGELOG.md b/sdk/storage/Azure.Storage.Blobs.ChangeFeed/CHANGELOG.md index 57d8f4071fe4..4a23db727b56 100644 --- a/sdk/storage/Azure.Storage.Blobs.ChangeFeed/CHANGELOG.md +++ b/sdk/storage/Azure.Storage.Blobs.ChangeFeed/CHANGELOG.md @@ -1,5 +1,8 @@ # Release History +## 12.0.0-preview.4 (2020-08-18) +- Bug in TaskExtensions.EnsureCompleted method that causes it to unconditionally throw an exception in the environments with synchronization context + ## 12.0.0-preview.3 (2020-08-13) - This release contains bug fixes to improve quality. diff --git a/sdk/storage/Azure.Storage.Blobs.ChangeFeed/src/Azure.Storage.Blobs.ChangeFeed.csproj b/sdk/storage/Azure.Storage.Blobs.ChangeFeed/src/Azure.Storage.Blobs.ChangeFeed.csproj index f38d7cb7060c..62fcd9218c2c 100644 --- a/sdk/storage/Azure.Storage.Blobs.ChangeFeed/src/Azure.Storage.Blobs.ChangeFeed.csproj +++ b/sdk/storage/Azure.Storage.Blobs.ChangeFeed/src/Azure.Storage.Blobs.ChangeFeed.csproj @@ -4,7 +4,7 @@ Microsoft Azure.Storage.Blobs.ChangeFeed client library - 12.0.0-preview.3 + 12.0.0-preview.4 ChangeFeedSDK;$(DefineConstants) Microsoft Azure Change Feed;Microsoft;Azure;Storage;StorageScalable;$(PackageCommonTags) diff --git a/sdk/storage/Azure.Storage.Blobs/CHANGELOG.md b/sdk/storage/Azure.Storage.Blobs/CHANGELOG.md index a50f592316db..d2ac602d75a0 100644 --- a/sdk/storage/Azure.Storage.Blobs/CHANGELOG.md +++ b/sdk/storage/Azure.Storage.Blobs/CHANGELOG.md @@ -1,5 +1,8 @@ # Release History +## 12.5.1 (2020-08-18) +- Bug in TaskExtensions.EnsureCompleted method that causes it to unconditionally throw an exception in the environments with synchronization context + ## 12.5.0 (2020-08-13) - Added support for custom local emulator hostname for blob storage endpoints. - Fixed bug where BlobContainerClient.SetAccessPolicy() sends DateTimeOffset.MinValue when StartsOn and ExpiresOn when not set in BlobAccessPolicy diff --git a/sdk/storage/Azure.Storage.Blobs/src/Azure.Storage.Blobs.csproj b/sdk/storage/Azure.Storage.Blobs/src/Azure.Storage.Blobs.csproj index e443fe77b53a..6c9f13726e2d 100644 --- a/sdk/storage/Azure.Storage.Blobs/src/Azure.Storage.Blobs.csproj +++ b/sdk/storage/Azure.Storage.Blobs/src/Azure.Storage.Blobs.csproj @@ -4,7 +4,7 @@ Microsoft Azure.Storage.Blobs client library - 12.5.0 + 12.5.1 12.4.4 BlobSDK;$(DefineConstants) Microsoft Azure Storage Blobs;Microsoft;Azure;Blobs;Blob;Storage;StorageScalable;$(PackageCommonTags) diff --git a/sdk/storage/Azure.Storage.Common/CHANGELOG.md b/sdk/storage/Azure.Storage.Common/CHANGELOG.md index 69c69f773a94..5468d8f2f8ee 100644 --- a/sdk/storage/Azure.Storage.Common/CHANGELOG.md +++ b/sdk/storage/Azure.Storage.Common/CHANGELOG.md @@ -1,5 +1,8 @@ # Release History +## 12.5.1 (2020-08-18) +- Bug in TaskExtensions.EnsureCompleted method that causes it to unconditionally throw an exception in the environments with synchronization context + ## 12.5.0 (2020-08-13) - This release contains bug fixes to improve quality. diff --git a/sdk/storage/Azure.Storage.Common/src/Azure.Storage.Common.csproj b/sdk/storage/Azure.Storage.Common/src/Azure.Storage.Common.csproj index 56de4cc44e61..cd03d0df586a 100644 --- a/sdk/storage/Azure.Storage.Common/src/Azure.Storage.Common.csproj +++ b/sdk/storage/Azure.Storage.Common/src/Azure.Storage.Common.csproj @@ -4,7 +4,7 @@ Microsoft Azure.Storage.Common client library - 12.5.0 + 12.5.1 12.4.3 CommonSDK;$(DefineConstants) Microsoft Azure Storage Common, Microsoft, Azure, StorageScalable, azureofficial diff --git a/sdk/storage/Azure.Storage.Files.DataLake/CHANGELOG.md b/sdk/storage/Azure.Storage.Files.DataLake/CHANGELOG.md index d264ca63703c..9f44c7f59a1f 100644 --- a/sdk/storage/Azure.Storage.Files.DataLake/CHANGELOG.md +++ b/sdk/storage/Azure.Storage.Files.DataLake/CHANGELOG.md @@ -1,5 +1,8 @@ # Release History +## 12.3.1 (2020-08-18) +- Bug in TaskExtensions.EnsureCompleted method that causes it to unconditionally throw an exception in the environments with synchronization context + ## 12.3.0 (2020-08-13) - Fixed bug where DataLakeFileSystemClient.SetAccessPolicy() sends DateTimeOffset.MinValue when StartsOn and ExpiresOn when not set in DataLakeAccessPolicy - Added nullable properties, PolicyStartsOn and PolicyExpiresOn to DataLakeAccessPolicy diff --git a/sdk/storage/Azure.Storage.Files.DataLake/src/Azure.Storage.Files.DataLake.csproj b/sdk/storage/Azure.Storage.Files.DataLake/src/Azure.Storage.Files.DataLake.csproj index 839123256275..268bcbfa5aa8 100644 --- a/sdk/storage/Azure.Storage.Files.DataLake/src/Azure.Storage.Files.DataLake.csproj +++ b/sdk/storage/Azure.Storage.Files.DataLake/src/Azure.Storage.Files.DataLake.csproj @@ -4,7 +4,7 @@ Microsoft Azure.Storage.Files.DataLake client library - 12.3.0 + 12.3.1 12.2.2 DataLakeSDK;$(DefineConstants) Microsoft Azure Storage Files;Microsoft;Azure;File;Files;Data Lake;Storage;StorageScalable;$(PackageCommonTags) diff --git a/sdk/storage/Azure.Storage.Files.Shares/CHANGELOG.md b/sdk/storage/Azure.Storage.Files.Shares/CHANGELOG.md index e2e9f363c692..5fa1316c9ea0 100644 --- a/sdk/storage/Azure.Storage.Files.Shares/CHANGELOG.md +++ b/sdk/storage/Azure.Storage.Files.Shares/CHANGELOG.md @@ -1,5 +1,8 @@ # Release History +## 12.3.1 (2020-08-18) +- Bug in TaskExtensions.EnsureCompleted method that causes it to unconditionally throw an exception in the environments with synchronization context + ## 12.3.0 (2020-08-13) - Fixed bug where ShareClient.SetAccessPolicy() sends DateTimeOffset.MinValue when StartsOn and ExpiresOn when not set in ShareAccessPolicy - Added nullable properties, PolicyStartsOn and PolicyExpiresOn to ShareAccessPolicy diff --git a/sdk/storage/Azure.Storage.Files.Shares/src/Azure.Storage.Files.Shares.csproj b/sdk/storage/Azure.Storage.Files.Shares/src/Azure.Storage.Files.Shares.csproj index 445412f69ef4..320bfc401fe8 100644 --- a/sdk/storage/Azure.Storage.Files.Shares/src/Azure.Storage.Files.Shares.csproj +++ b/sdk/storage/Azure.Storage.Files.Shares/src/Azure.Storage.Files.Shares.csproj @@ -4,7 +4,7 @@ Microsoft Azure.Storage.Files.Shares client library - 12.3.0 + 12.3.1 12.2.3 FileSDK;$(DefineConstants) Microsoft Azure Storage Files;Microsoft;Azure;File;Files;Storage;StorageScalable;$(PackageCommonTags) diff --git a/sdk/storage/Azure.Storage.Queues/CHANGELOG.md b/sdk/storage/Azure.Storage.Queues/CHANGELOG.md index 5973545b9bbd..42fd91f2166f 100644 --- a/sdk/storage/Azure.Storage.Queues/CHANGELOG.md +++ b/sdk/storage/Azure.Storage.Queues/CHANGELOG.md @@ -1,5 +1,8 @@ # Release History +## 12.4.1 (2020-08-18) +- Bug in TaskExtensions.EnsureCompleted method that causes it to unconditionally throw an exception in the environments with synchronization context + ## 12.4.0 (2020-08-13) - This preview contains bug fixes to improve quality. diff --git a/sdk/storage/Azure.Storage.Queues/src/Azure.Storage.Queues.csproj b/sdk/storage/Azure.Storage.Queues/src/Azure.Storage.Queues.csproj index 222256096228..3c57f7032453 100644 --- a/sdk/storage/Azure.Storage.Queues/src/Azure.Storage.Queues.csproj +++ b/sdk/storage/Azure.Storage.Queues/src/Azure.Storage.Queues.csproj @@ -4,7 +4,7 @@ Microsoft Azure.Storage.Queues client library - 12.4.0 + 12.4.1 12.3.2 QueueSDK;$(DefineConstants) Microsoft Azure Storage Queues;Microsoft;Azure;Queues;Queue;Storage;StorageScalable;$(PackageCommonTags)