Add and use public TaskToAsyncResult helper type (#82557)
authorStephen Toub <stoub@microsoft.com>
Fri, 24 Feb 2023 16:59:28 +0000 (11:59 -0500)
committerGitHub <noreply@github.com>
Fri, 24 Feb 2023 16:59:28 +0000 (11:59 -0500)
* Add and use public TaskToAsyncResult helper type

* Disable thread blocking test on browser

74 files changed:
src/libraries/Common/src/System/IO/ReadOnlyMemoryStream.cs
src/libraries/Common/src/System/Threading/Tasks/TaskToApm.cs [deleted file]
src/libraries/Common/src/System/Threading/Tasks/TaskToAsyncResult.cs [new file with mode: 0644]
src/libraries/Common/tests/Common.Tests.csproj
src/libraries/Common/tests/StreamConformanceTests/StreamConformanceTests.csproj
src/libraries/Common/tests/System/IO/Compression/CompressionStreamUnitTestBase.cs
src/libraries/Common/tests/System/IO/ConnectedStreams.cs
src/libraries/Common/tests/System/IO/DelayStream.cs
src/libraries/System.IO.Compression.Brotli/src/System.IO.Compression.Brotli.csproj
src/libraries/System.IO.Compression.Brotli/src/System/IO/Compression/dec/BrotliStream.Decompress.cs
src/libraries/System.IO.Compression.Brotli/src/System/IO/Compression/enc/BrotliStream.Compress.cs
src/libraries/System.IO.Compression.Brotli/tests/System.IO.Compression.Brotli.Tests.csproj
src/libraries/System.IO.Compression/src/System.IO.Compression.csproj
src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateManaged/DeflateManagedStream.cs
src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateZLib/DeflateStream.cs
src/libraries/System.IO.Compression/src/System/IO/Compression/GZipStream.cs
src/libraries/System.IO.Compression/tests/System.IO.Compression.Tests.csproj
src/libraries/System.IO.Pipelines/src/System.IO.Pipelines.csproj
src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/PipeReaderStream.cs
src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/PipeWriterStream.cs
src/libraries/System.IO.Pipes/src/System.IO.Pipes.csproj
src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeServerStream.cs
src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Unix.cs
src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Windows.cs
src/libraries/System.IO.Ports/src/System.IO.Ports.csproj
src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Unix.cs
src/libraries/System.IO/tests/System.IO.Tests.csproj
src/libraries/System.Memory.Data/src/System.Memory.Data.csproj
src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj
src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestStream.cs
src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpResponseStream.cs
src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/System.Net.Http.WinHttpHandler.Unit.Tests.csproj
src/libraries/System.Net.Http/src/System.Net.Http.csproj
src/libraries/System.Net.Http/src/System/Net/Http/HttpBaseStream.cs
src/libraries/System.Net.Http/src/System/Net/Http/HttpContent.cs
src/libraries/System.Net.Http/src/System/Net/Http/MultipartContent.cs
src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj
src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj
src/libraries/System.Net.HttpListener/src/System.Net.HttpListener.csproj
src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj
src/libraries/System.Net.NameResolution/src/System/Net/Dns.cs
src/libraries/System.Net.NetworkInformation/src/System.Net.NetworkInformation.csproj
src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemIPGlobalProperties.cs
src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/UnixIPGlobalProperties.cs
src/libraries/System.Net.Quic/src/System.Net.Quic.csproj
src/libraries/System.Net.Quic/src/System/Net/Quic/QuicStream.Stream.cs
src/libraries/System.Net.Quic/tests/FunctionalTests/System.Net.Quic.Functional.Tests.csproj
src/libraries/System.Net.Requests/src/System.Net.Requests.csproj
src/libraries/System.Net.Requests/src/System/Net/FileWebRequest.cs
src/libraries/System.Net.Security/src/System.Net.Security.csproj
src/libraries/System.Net.Security/src/System/Net/Security/NegotiateStream.cs
src/libraries/System.Net.Security/src/System/Net/Security/SslStream.cs
src/libraries/System.Net.Security/tests/EnterpriseTests/System.Net.Security.Enterprise.Tests.csproj
src/libraries/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj
src/libraries/System.Net.Security/tests/FunctionalTests/result.txt [deleted file]
src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj
src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj
src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs
src/libraries/System.Net.Sockets/src/System/Net/Sockets/TCPListener.cs
src/libraries/System.Net.Sockets/tests/FunctionalTests/System.Net.Sockets.Tests.csproj
src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
src/libraries/System.Private.CoreLib/src/System/IO/BufferedStream.cs
src/libraries/System.Private.CoreLib/src/System/IO/Strategies/BufferedFileStreamStrategy.cs
src/libraries/System.Private.CoreLib/src/System/IO/Strategies/OSFileStreamStrategy.cs
src/libraries/System.Private.CoreLib/src/System/IO/Stream.cs
src/libraries/System.Private.CoreLib/src/System/Text/TranscodingStream.cs
src/libraries/System.Runtime/ref/System.Runtime.cs
src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj
src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CryptoStream.cs
src/libraries/System.Security.Cryptography/tests/System.Security.Cryptography.Tests.csproj
src/libraries/System.Text.Encoding/tests/System.Text.Encoding.Tests.csproj
src/libraries/System.Threading.Tasks/tests/System.Threading.Tasks.Tests.csproj
src/libraries/System.Threading.Tasks/tests/TaskToAsyncResultTests.cs [new file with mode: 0644]
src/mono/mono/tests/threadpool-exceptions8.cs

index 5e73fd5..8bc8320 100644 (file)
@@ -143,12 +143,12 @@ namespace System.IO
 #endif
 
         public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) =>
-            TaskToApm.Begin(ReadAsync(buffer, offset, count), callback, state);
+            TaskToAsyncResult.Begin(ReadAsync(buffer, offset, count), callback, state);
 
         public override int EndRead(IAsyncResult asyncResult)
         {
             EnsureNotClosed();
-            return TaskToApm.End<int>(asyncResult);
+            return TaskToAsyncResult.End<int>(asyncResult);
         }
 
 #if !NETFRAMEWORK && !NETSTANDARD2_0
diff --git a/src/libraries/Common/src/System/Threading/Tasks/TaskToApm.cs b/src/libraries/Common/src/System/Threading/Tasks/TaskToApm.cs
deleted file mode 100644 (file)
index a308e1d..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-// Helper methods for using Tasks to implement the APM pattern.
-//
-// Example usage, wrapping a Task<int>-returning FooAsync method with Begin/EndFoo methods:
-//
-//     public IAsyncResult BeginFoo(..., AsyncCallback? callback, object? state) =>
-//         TaskToApm.Begin(FooAsync(...), callback, state);
-//
-//     public int EndFoo(IAsyncResult asyncResult) =>
-//         TaskToApm.End<int>(asyncResult);
-
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-
-namespace System.Threading.Tasks
-{
-    /// <summary>
-    /// Provides support for efficiently using Tasks to implement the APM (Begin/End) pattern.
-    /// </summary>
-    internal static class TaskToApm
-    {
-        /// <summary>
-        /// Marshals the Task as an IAsyncResult, using the supplied callback and state
-        /// to implement the APM pattern.
-        /// </summary>
-        /// <param name="task">The Task to be marshaled.</param>
-        /// <param name="callback">The callback to be invoked upon completion.</param>
-        /// <param name="state">The state to be stored in the IAsyncResult.</param>
-        /// <returns>An IAsyncResult to represent the task's asynchronous operation.</returns>
-        public static IAsyncResult Begin(Task task, AsyncCallback? callback, object? state) =>
-            new TaskAsyncResult(task, state, callback);
-
-        /// <summary>Processes an IAsyncResult returned by Begin.</summary>
-        /// <param name="asyncResult">The IAsyncResult to unwrap.</param>
-        public static void End(IAsyncResult asyncResult)
-        {
-            if (GetTask(asyncResult) is Task t)
-            {
-                t.GetAwaiter().GetResult();
-                return;
-            }
-
-            ThrowArgumentException(asyncResult);
-        }
-
-        /// <summary>Processes an IAsyncResult returned by Begin.</summary>
-        /// <param name="asyncResult">The IAsyncResult to unwrap.</param>
-        public static TResult End<TResult>(IAsyncResult asyncResult)
-        {
-            if (GetTask(asyncResult) is Task<TResult> task)
-            {
-                return task.GetAwaiter().GetResult();
-            }
-
-            ThrowArgumentException(asyncResult);
-            return default!; // unreachable
-        }
-
-        /// <summary>Gets the task represented by the IAsyncResult.</summary>
-        public static Task? GetTask(IAsyncResult asyncResult) => (asyncResult as TaskAsyncResult)?._task;
-
-        /// <summary>Throws an argument exception for the invalid <paramref name="asyncResult"/>.</summary>
-        [DoesNotReturn]
-        private static void ThrowArgumentException(IAsyncResult asyncResult)
-        {
-            throw asyncResult is null ?
-                new ArgumentNullException(nameof(asyncResult)) :
-                new ArgumentException(null, nameof(asyncResult));
-        }
-
-        /// <summary>Provides a simple IAsyncResult that wraps a Task.</summary>
-        /// <remarks>
-        /// We could use the Task as the IAsyncResult if the Task's AsyncState is the same as the object state,
-        /// but that's very rare, in particular in a situation where someone cares about allocation, and always
-        /// using TaskAsyncResult simplifies things and enables additional optimizations.
-        /// </remarks>
-        internal sealed class TaskAsyncResult : IAsyncResult
-        {
-            /// <summary>The wrapped Task.</summary>
-            internal readonly Task _task;
-            /// <summary>Callback to invoke when the wrapped task completes.</summary>
-            private readonly AsyncCallback? _callback;
-
-            /// <summary>Initializes the IAsyncResult with the Task to wrap and the associated object state.</summary>
-            /// <param name="task">The Task to wrap.</param>
-            /// <param name="state">The new AsyncState value.</param>
-            /// <param name="callback">Callback to invoke when the wrapped task completes.</param>
-            internal TaskAsyncResult(Task task, object? state, AsyncCallback? callback)
-            {
-                Debug.Assert(task != null);
-                _task = task;
-                AsyncState = state;
-
-                if (task.IsCompleted)
-                {
-                    // Synchronous completion.  Invoke the callback.  No need to store it.
-                    CompletedSynchronously = true;
-                    callback?.Invoke(this);
-                }
-                else if (callback != null)
-                {
-                    // Asynchronous completion, and we have a callback; schedule it. We use OnCompleted rather than ContinueWith in
-                    // order to avoid running synchronously if the task has already completed by the time we get here but still run
-                    // synchronously as part of the task's completion if the task completes after (the more common case).
-                    _callback = callback;
-                    _task.ConfigureAwait(continueOnCapturedContext: false)
-                         .GetAwaiter()
-                         .OnCompleted(InvokeCallback); // allocates a delegate, but avoids a closure
-                }
-            }
-
-            /// <summary>Invokes the callback.</summary>
-            private void InvokeCallback()
-            {
-                Debug.Assert(!CompletedSynchronously);
-                Debug.Assert(_callback != null);
-                _callback.Invoke(this);
-            }
-
-            /// <summary>Gets a user-defined object that qualifies or contains information about an asynchronous operation.</summary>
-            public object? AsyncState { get; }
-            /// <summary>Gets a value that indicates whether the asynchronous operation completed synchronously.</summary>
-            /// <remarks>This is set lazily based on whether the <see cref="_task"/> has completed by the time this object is created.</remarks>
-            public bool CompletedSynchronously { get; }
-            /// <summary>Gets a value that indicates whether the asynchronous operation has completed.</summary>
-            public bool IsCompleted => _task.IsCompleted;
-            /// <summary>Gets a <see cref="WaitHandle"/> that is used to wait for an asynchronous operation to complete.</summary>
-            public WaitHandle AsyncWaitHandle => ((IAsyncResult)_task).AsyncWaitHandle;
-        }
-    }
-}
diff --git a/src/libraries/Common/src/System/Threading/Tasks/TaskToAsyncResult.cs b/src/libraries/Common/src/System/Threading/Tasks/TaskToAsyncResult.cs
new file mode 100644 (file)
index 0000000..fdfd25e
--- /dev/null
@@ -0,0 +1,171 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Diagnostics;
+
+namespace System.Threading.Tasks
+{
+    /// <summary>
+    /// Provides methods for using <see cref="Task"/> to implement the Asynchronous Programming Model
+    /// pattern based on "Begin" and "End" methods.
+    /// </summary>
+#if SYSTEM_PRIVATE_CORELIB
+    public
+#else
+    internal
+#endif
+    static class TaskToAsyncResult
+    {
+        /// <summary>Creates a new <see cref="IAsyncResult"/> from the specified <see cref="Task"/>, optionally invoking <paramref name="callback"/> when the task has completed.</summary>
+        /// <param name="task">The <see cref="Task"/> to be wrapped in an <see cref="IAsyncResult"/>.</param>
+        /// <param name="callback">The callback to be invoked upon <paramref name="task"/>'s completion. If <see langword="null"/>, no callback will be invoked.</param>
+        /// <param name="state">The state to be stored in the <see cref="IAsyncResult"/>.</param>
+        /// <returns>An <see cref="IAsyncResult"/> to represent the task's asynchronous operation. This instance will also be passed to <paramref name="callback"/> when it's invoked.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="task"/> is null.</exception>
+        /// <remarks>
+        /// In conjunction with the <see cref="End(IAsyncResult)"/> or <see cref="End{TResult}(IAsyncResult)"/> methods, this method may be used
+        /// to implement the Begin/End pattern (also known as the Asynchronous Programming Model pattern, or APM). It is recommended to not expose this pattern
+        /// in new code; the methods on <see cref="TaskToAsyncResult"/> are intended only to help implement such Begin/End methods when they must be exposed, for example
+        /// because a base class provides virtual methods for the pattern, or when they've already been exposed and must remain for compatibility.  These methods enable
+        /// implementing all of the core asynchronous logic via <see cref="Task"/>s and then easily implementing Begin/End methods around that functionality.
+        /// </remarks>
+        public static IAsyncResult Begin(Task task, AsyncCallback? callback, object? state)
+        {
+#if NET6_0_OR_GREATER
+            ArgumentNullException.ThrowIfNull(task);
+#else
+            if (task is null)
+            {
+                throw new ArgumentNullException(nameof(task));
+            }
+#endif
+
+            return new TaskAsyncResult(task, state, callback);
+        }
+
+        /// <summary>Waits for the <see cref="Task"/> wrapped by the <see cref="IAsyncResult"/> returned by <see cref="Begin"/> to complete.</summary>
+        /// <param name="asyncResult">The <see cref="IAsyncResult"/> for which to wait.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="asyncResult"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="asyncResult"/> was not produced by a call to <see cref="Begin"/>.</exception>
+        /// <remarks>This will propagate any exception stored in the wrapped <see cref="Task"/>.</remarks>
+        public static void End(IAsyncResult asyncResult) =>
+            Unwrap(asyncResult).GetAwaiter().GetResult();
+
+        /// <summary>Waits for the <see cref="Task{TResult}"/> wrapped by the <see cref="IAsyncResult"/> returned by <see cref="Begin"/> to complete.</summary>
+        /// <param name="asyncResult">The <see cref="IAsyncResult"/> for which to wait.</param>
+        /// <returns>The result of the <see cref="Task{TResult}"/> wrapped by the <see cref="IAsyncResult"/>.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="asyncResult"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="asyncResult"/> was not produced by a call to <see cref="Begin"/>.</exception>
+        /// <remarks>This will propagate any exception stored in the wrapped <see cref="Task{TResult}"/>.</remarks>
+        public static TResult End<TResult>(IAsyncResult asyncResult) =>
+            Unwrap<TResult>(asyncResult).GetAwaiter().GetResult();
+
+        /// <summary>Extracts the underlying <see cref="Task"/> from an <see cref="IAsyncResult"/> created by <see cref="Begin"/>.</summary>
+        /// <param name="asyncResult">The <see cref="IAsyncResult"/> created by <see cref="Begin"/>.</param>
+        /// <returns>The <see cref="Task"/> wrapped by the <see cref="IAsyncResult"/>.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="asyncResult"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="asyncResult"/> was not produced by a call to <see cref="Begin"/>.</exception>
+        public static Task Unwrap(IAsyncResult asyncResult)
+        {
+#if NET6_0_OR_GREATER
+            ArgumentNullException.ThrowIfNull(asyncResult);
+#else
+            if (asyncResult is null)
+            {
+                throw new ArgumentNullException(nameof(asyncResult));
+            }
+#endif
+
+            if ((asyncResult as TaskAsyncResult)?._task is not Task task)
+            {
+                throw new ArgumentException(null, nameof(asyncResult));
+            }
+
+            return task;
+        }
+
+        /// <summary>Extracts the underlying <see cref="Task{TResult}"/> from an <see cref="IAsyncResult"/> created by <see cref="Begin"/>.</summary>
+        /// <param name="asyncResult">The <see cref="IAsyncResult"/> created by <see cref="Begin"/>.</param>
+        /// <returns>The <see cref="Task{TResult}"/> wrapped by the <see cref="IAsyncResult"/>.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="asyncResult"/> is null.</exception>
+        /// <exception cref="ArgumentException">
+        /// <paramref name="asyncResult"/> was not produced by a call to <see cref="Begin"/>,
+        /// or the <see cref="Task{TResult}"/> provided to <see cref="Begin"/> was used a generic type parameter
+        /// that's different from the <typeparamref name="TResult"/> supplied to this call.
+        /// </exception>
+        public static Task<TResult> Unwrap<TResult>(IAsyncResult asyncResult)
+        {
+#if NET6_0_OR_GREATER
+            ArgumentNullException.ThrowIfNull(asyncResult);
+#else
+            if (asyncResult is null)
+            {
+                throw new ArgumentNullException(nameof(asyncResult));
+            }
+#endif
+
+            if ((asyncResult as TaskAsyncResult)?._task is not Task<TResult> task)
+            {
+                throw new ArgumentException(null, nameof(asyncResult));
+            }
+
+            return task;
+        }
+
+        /// <summary>Provides a simple <see cref="IAsyncResult"/> that wraps a <see cref="Task"/>.</summary>
+        /// <remarks>
+        /// We could use the Task as the IAsyncResult if the Task's AsyncState is the same as the object state,
+        /// but that's very rare, in particular in a situation where someone cares about allocation, and always
+        /// using TaskAsyncResult simplifies things and enables additional optimizations.
+        /// </remarks>
+        private sealed class TaskAsyncResult : IAsyncResult
+        {
+            /// <summary>The wrapped Task.</summary>
+            internal readonly Task _task;
+            /// <summary>Callback to invoke when the wrapped task completes.</summary>
+            private readonly AsyncCallback? _callback;
+
+            /// <summary>Initializes the IAsyncResult with the Task to wrap and the associated object state.</summary>
+            /// <param name="task">The Task to wrap.</param>
+            /// <param name="state">The new AsyncState value.</param>
+            /// <param name="callback">Callback to invoke when the wrapped task completes.</param>
+            internal TaskAsyncResult(Task task, object? state, AsyncCallback? callback)
+            {
+                Debug.Assert(task is not null);
+
+                _task = task;
+                AsyncState = state;
+
+                if (task.IsCompleted)
+                {
+                    // The task has already completed.  Treat this as synchronous completion.
+                    // Invoke the callback; no need to store it.
+                    CompletedSynchronously = true;
+                    callback?.Invoke(this);
+                }
+                else if (callback is not null)
+                {
+                    // Asynchronous completion, and we have a callback; schedule it. We use OnCompleted rather than ContinueWith in
+                    // order to avoid running synchronously if the task has already completed by the time we get here but still run
+                    // synchronously as part of the task's completion if the task completes after (the more common case).
+                    _callback = callback;
+                    _task.ConfigureAwait(continueOnCapturedContext: false)
+                         .GetAwaiter()
+                         .OnCompleted(() => _callback.Invoke(this));
+                }
+            }
+
+            /// <inheritdoc/>
+            public object? AsyncState { get; }
+
+            /// <inheritdoc/>
+            public bool CompletedSynchronously { get; }
+
+            /// <inheritdoc/>
+            public bool IsCompleted => _task.IsCompleted;
+
+            /// <inheritdoc/>
+            public WaitHandle AsyncWaitHandle => ((IAsyncResult)_task).AsyncWaitHandle;
+        }
+    }
+}
index 372048c..5ed2a1e 100644 (file)
              Link="System\Net\Sockets\Fletcher32.cs" />
     <Compile Include="$(CommonPath)System\Net\Logging\NetEventSource.Common.cs"
              Link="Common\System\Net\Logging\NetEventSource.Common.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="Common\System\Threading\Tasks\TaskToApm.cs" />
     <Compile Include="$(CommonPath)System\IO\PathInternal.cs"
              Link="System\IO\PathInternal.cs" />
     <Compile Include="System\IO\ConnectedStreams.cs" Link="System\IO\ConnectedStreams.cs" />
index 5514898..eebde98 100644 (file)
@@ -8,7 +8,6 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="$(CommonTestPath)System\IO\ConnectedStreams.cs" Link="System\IO\ConnectedStreams.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs" Link="System\Threading\Tasks\TaskToApm.cs" />
     <Compile Include="$(CommonPath)System\Net\ArrayBuffer.cs" Link="Common\System\Net\ArrayBuffer.cs" />
     <Compile Include="$(CommonPath)System\Net\MultiArrayBuffer.cs" Link="Common\System\Net\MultiArrayBuffer.cs" />
     <Compile Include="$(CommonPath)System\Net\StreamBuffer.cs" Link="Common\System\Net\StreamBuffer.cs" />
index 31156d7..17ec46f 100644 (file)
@@ -549,10 +549,10 @@ namespace System.IO.Compression
             isSync = sync;
         }
 
-        public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) => TaskToApm.Begin(ReadAsync(buffer, offset, count), callback, state);
-        public override int EndRead(IAsyncResult asyncResult) => TaskToApm.End<int>(asyncResult);
-        public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) => TaskToApm.Begin(WriteAsync(buffer, offset, count), callback, state);
-        public override void EndWrite(IAsyncResult asyncResult) => TaskToApm.End(asyncResult);
+        public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) => TaskToAsyncResult.Begin(ReadAsync(buffer, offset, count), callback, state);
+        public override int EndRead(IAsyncResult asyncResult) => TaskToAsyncResult.End<int>(asyncResult);
+        public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) => TaskToAsyncResult.Begin(WriteAsync(buffer, offset, count), callback, state);
+        public override void EndWrite(IAsyncResult asyncResult) => TaskToAsyncResult.End(asyncResult);
 
         public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
         {
index b8f3fe1..f5da8c8 100644 (file)
@@ -159,14 +159,14 @@ namespace System.IO
             }
 
             public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) =>
-                TaskToApm.Begin(ReadAsync(buffer, offset, count), callback, state);
+                TaskToAsyncResult.Begin(ReadAsync(buffer, offset, count), callback, state);
 
             public override int EndRead(IAsyncResult asyncResult)
             {
                 ThrowIfDisposed();
                 ThrowIfReadingNotSupported();
 
-                return TaskToApm.End<int>(asyncResult);
+                return TaskToAsyncResult.End<int>(asyncResult);
             }
 
             public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
@@ -229,14 +229,14 @@ namespace System.IO
             }
 
             public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) =>
-                TaskToApm.Begin(WriteAsync(buffer, offset, count), callback, state);
+                TaskToAsyncResult.Begin(WriteAsync(buffer, offset, count), callback, state);
 
             public override void EndWrite(IAsyncResult asyncResult)
             {
                 ThrowIfDisposed();
                 ThrowIfWritingNotSupported();
 
-                TaskToApm.End(asyncResult);
+                TaskToAsyncResult.End(asyncResult);
             }
 
             public override long Length => throw new NotSupportedException();
@@ -348,12 +348,12 @@ namespace System.IO
             }
 
             public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) =>
-                TaskToApm.Begin(ReadAsync(buffer, offset, count), callback, state);
+                TaskToAsyncResult.Begin(ReadAsync(buffer, offset, count), callback, state);
 
             public override int EndRead(IAsyncResult asyncResult)
             {
                 ThrowIfDisposed();
-                return TaskToApm.End<int>(asyncResult);
+                return TaskToAsyncResult.End<int>(asyncResult);
             }
 
             public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
@@ -402,12 +402,12 @@ namespace System.IO
             }
 
             public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) =>
-                TaskToApm.Begin(WriteAsync(buffer, offset, count), callback, state);
+                TaskToAsyncResult.Begin(WriteAsync(buffer, offset, count), callback, state);
 
             public override void EndWrite(IAsyncResult asyncResult)
             {
                 ThrowIfDisposed();
-                TaskToApm.End(asyncResult);
+                TaskToAsyncResult.End(asyncResult);
             }
 
             public override long Length => throw new NotSupportedException();
index aeb6678..e0ece4e 100644 (file)
@@ -43,9 +43,9 @@ namespace System.IO
         }
 
         public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) =>
-            TaskToApm.Begin(ReadAsync(buffer, offset, count), callback, state);
+            TaskToAsyncResult.Begin(ReadAsync(buffer, offset, count), callback, state);
 
-        public override int EndRead(IAsyncResult asyncResult) => TaskToApm.End<int>(asyncResult);
+        public override int EndRead(IAsyncResult asyncResult) => TaskToAsyncResult.End<int>(asyncResult);
 
         public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
         {
@@ -72,9 +72,9 @@ namespace System.IO
         }
 
         public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) =>
-            TaskToApm.Begin(WriteAsync(buffer, offset, count), callback, state);
+            TaskToAsyncResult.Begin(WriteAsync(buffer, offset, count), callback, state);
 
-        public override void EndWrite(IAsyncResult asyncResult) => TaskToApm.End(asyncResult);
+        public override void EndWrite(IAsyncResult asyncResult) => TaskToAsyncResult.End(asyncResult);
 
         public override void Write(byte[] buffer, int offset, int count)
         {
index 6c884b2..df43122 100644 (file)
@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <TargetFrameworks>$(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-unix;$(NetCoreAppCurrent)</TargetFrameworks>
@@ -20,8 +20,6 @@
     <Compile Include="System\IO\Compression\enc\BrotliEncoderOperation.cs" />
     <Compile Include="System\IO\Compression\enc\BrotliEncoderParameter.cs" />
     <Compile Include="System\IO\Compression\BrotliStream.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="Common\System\Threading\Tasks\TaskToApm.cs" />
     <Compile Include="$(CommonPath)Microsoft\Win32\SafeHandles\SafeBrotliHandle.cs"
              Link="Common\Microsoft\Win32\SafeHandles\SafeBrotliHandle.cs" />
   </ItemGroup>
index be4fe9d..ac596b9 100644 (file)
@@ -96,7 +96,7 @@ namespace System.IO.Compression
         /// <exception cref="System.NotSupportedException">The current <see cref="System.IO.Compression.BrotliStream" /> implementation does not support the read operation.</exception>
         /// <exception cref="System.InvalidOperationException">This call cannot be completed.</exception>
         public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState) =>
-            TaskToApm.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
+            TaskToAsyncResult.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
 
         /// <summary>Waits for the pending asynchronous read to complete. (Consider using the <see cref="System.IO.Stream.ReadAsync(byte[],int,int)" /> method instead.)</summary>
         /// <param name="asyncResult">The reference to the pending asynchronous request to finish.</param>
@@ -105,7 +105,7 @@ namespace System.IO.Compression
         /// <exception cref="System.ArgumentException"><paramref name="asyncResult" /> did not originate from a <see cref="System.IO.Compression.BrotliStream.BeginRead(byte[],int,int,System.AsyncCallback,object)" /> method on the current stream.</exception>
         /// <exception cref="System.InvalidOperationException">The end operation cannot be performed because the stream is closed.</exception>
         public override int EndRead(IAsyncResult asyncResult) =>
-            TaskToApm.End<int>(asyncResult);
+            TaskToAsyncResult.End<int>(asyncResult);
 
         /// <summary>Asynchronously reads a sequence of bytes from the current Brotli stream, writes them to a byte array starting at a specified index, advances the position within the Brotli stream by the number of bytes read, and monitors cancellation requests.</summary>
         /// <param name="buffer">The buffer to write the data into.</param>
index 1ecfc0b..207c552 100644 (file)
@@ -94,13 +94,13 @@ namespace System.IO.Compression
         /// <exception cref="System.NotSupportedException">The current <see cref="System.IO.Compression.BrotliStream" /> implementation does not support the write operation.</exception>
         /// <exception cref="System.InvalidOperationException">The write operation cannot be performed because the stream is closed.</exception>
         public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState) =>
-            TaskToApm.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
+            TaskToAsyncResult.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
 
         /// <summary>Handles the end of an asynchronous write operation. (Consider using the <see cref="System.IO.Stream.WriteAsync(byte[],int,int)" /> method instead.)</summary>
         /// <param name="asyncResult">The object that represents the asynchronous call.</param>
         /// <exception cref="System.InvalidOperationException">The underlying stream is closed or <see langword="null" />.</exception>
         public override void EndWrite(IAsyncResult asyncResult) =>
-            TaskToApm.End(asyncResult);
+            TaskToAsyncResult.End(asyncResult);
 
         /// <summary>Asynchronously writes compressed bytes to the underlying Brotli stream from the specified byte array.</summary>
         /// <param name="buffer">The buffer that contains the data to compress.</param>
index 64fa67a..167caaa 100644 (file)
@@ -24,8 +24,6 @@
              Link="Common\System\IO\Compression\ZipTestHelper.cs" />
     <Compile Include="$(CommonTestPath)System\IO\TempFile.cs"
              Link="Common\System\IO\TempFile.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="Common\System\Threading\Tasks\TaskToApm.cs" />
     <Compile Include="$(CommonTestPath)System\IO\ConnectedStreams.cs" Link="Common\System\IO\ConnectedStreams.cs" />
     <Compile Include="$(CommonPath)System\Net\MultiArrayBuffer.cs" Link="ProductionCode\Common\System\Net\MultiArrayBuffer.cs" />
     <Compile Include="$(CommonPath)System\Net\StreamBuffer.cs" Link="ProductionCode\Common\System\Net\StreamBuffer.cs" />
index d05a1d7..798fccd 100644 (file)
@@ -39,8 +39,6 @@
     <Compile Include="System\IO\Compression\GZipStream.cs" />
     <Compile Include="System\IO\Compression\PositionPreservingWriteOnlyStreamWrapper.cs" />
     <Compile Include="System\IO\Compression\ZLibStream.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="Common\System\Threading\Tasks\TaskToApm.cs" />
   </ItemGroup>
   <!-- Windows specific files -->
   <ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'windows'">
index 96baf10..d161f74 100644 (file)
@@ -152,10 +152,10 @@ namespace System.IO.Compression
         }
 
         public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState) =>
-            TaskToApm.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
+            TaskToAsyncResult.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
 
         public override int EndRead(IAsyncResult asyncResult) =>
-            TaskToApm.End<int>(asyncResult);
+            TaskToAsyncResult.End<int>(asyncResult);
 
         private ValueTask<int> ReadAsyncInternal(Memory<byte> buffer, CancellationToken cancellationToken)
         {
index 2afd554..18b6cb9 100644 (file)
@@ -356,13 +356,13 @@ namespace System.IO.Compression
             throw new InvalidDataException(SR.TruncatedData);
 
         public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState) =>
-            TaskToApm.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
+            TaskToAsyncResult.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
 
         public override int EndRead(IAsyncResult asyncResult)
         {
             EnsureDecompressionMode();
             EnsureNotDisposed();
-            return TaskToApm.End<int>(asyncResult);
+            return TaskToAsyncResult.End<int>(asyncResult);
         }
 
         public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
@@ -758,13 +758,13 @@ namespace System.IO.Compression
         }
 
         public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState) =>
-            TaskToApm.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
+            TaskToAsyncResult.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
 
         public override void EndWrite(IAsyncResult asyncResult)
         {
             EnsureCompressionMode();
             EnsureNotDisposed();
-            TaskToApm.End(asyncResult);
+            TaskToAsyncResult.End(asyncResult);
         }
 
         public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
index f59e473..c4b743b 100644 (file)
@@ -72,7 +72,7 @@ namespace System.IO.Compression
         }
 
         public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState) =>
-            TaskToApm.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
+            TaskToAsyncResult.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
 
         public override int EndRead(IAsyncResult asyncResult) =>
             _deflateStream.EndRead(asyncResult);
@@ -100,7 +100,7 @@ namespace System.IO.Compression
         }
 
         public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState) =>
-            TaskToApm.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
+            TaskToAsyncResult.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
 
         public override void EndWrite(IAsyncResult asyncResult) =>
             _deflateStream.EndWrite(asyncResult);
index 518be0f..7715606 100644 (file)
@@ -39,7 +39,6 @@
     <Compile Include="$(CommonTestPath)System\IO\WrappedStream.cs" Link="Common\System\IO\WrappedStream.cs" />
     <Compile Include="$(CommonTestPath)System\IO\Compression\ZipTestHelper.cs" Link="Common\System\IO\Compression\ZipTestHelper.cs" />
     <Compile Include="$(CommonTestPath)TestUtilities\System\DisableParallelization.cs" Link="Common\TestUtilities\System\DisableParallelization.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs" Link="Common\System\Threading\Tasks\TaskToApm.cs" />
     <Compile Include="$(CommonTestPath)System\IO\ConnectedStreams.cs" Link="Common\System\IO\ConnectedStreams.cs" />
     <Compile Include="$(CommonPath)System\Net\MultiArrayBuffer.cs" Link="ProductionCode\Common\System\Net\MultiArrayBuffer.cs" />
     <Compile Include="$(CommonPath)System\Net\StreamBuffer.cs" Link="ProductionCode\Common\System\Net\StreamBuffer.cs" />
index 33678ec..21a7012 100644 (file)
@@ -11,8 +11,6 @@ System.IO.Pipelines.PipeReader</PackageDescription>
   </PropertyGroup>
 
   <ItemGroup>
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="Common\System\Threading\Tasks\TaskToApm.cs" />
     <Compile Include="Properties\InternalsVisibleTo.cs" />
     <Compile Include="System\IO\Pipelines\BufferSegment.cs" />
     <Compile Include="System\IO\Pipelines\CompletionData.cs" />
@@ -57,6 +55,10 @@ System.IO.Pipelines.PipeReader</PackageDescription>
     <Compile Include="System\IO\Pipelines\CancellationTokenExtensions.netstandard.cs" />
   </ItemGroup>
 
+  <ItemGroup Condition="!$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))">
+    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToAsyncResult.cs" Link="Common\System\Threading\Tasks\TaskToAsyncResult.cs" />
+  </ItemGroup>
+
   <ItemGroup Condition="'$(TargetFrameworkIdentifier)' != '.NETCoreApp'">
     <PackageReference Include="System.Buffers" Version="$(SystemBuffersVersion)" />
     <PackageReference Include="System.Memory" Version="$(SystemMemoryVersion)" />
index 19128cc..798defa 100644 (file)
@@ -75,10 +75,10 @@ namespace System.IO.Pipelines
         public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException();
 
         public sealed override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) =>
-            TaskToApm.Begin(ReadAsync(buffer, offset, count, default), callback, state);
+            TaskToAsyncResult.Begin(ReadAsync(buffer, offset, count, default), callback, state);
 
         public sealed override int EndRead(IAsyncResult asyncResult) =>
-            TaskToApm.End<int>(asyncResult);
+            TaskToAsyncResult.End<int>(asyncResult);
 
         public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
         {
index dc9c34a..2dc15a5 100644 (file)
@@ -61,10 +61,10 @@ namespace System.IO.Pipelines
         public override void SetLength(long value) => throw new NotSupportedException();
 
         public sealed override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) =>
-            TaskToApm.Begin(WriteAsync(buffer, offset, count, default), callback, state);
+            TaskToAsyncResult.Begin(WriteAsync(buffer, offset, count, default), callback, state);
 
         public sealed override void EndWrite(IAsyncResult asyncResult) =>
-            TaskToApm.End(asyncResult);
+            TaskToAsyncResult.End(asyncResult);
 
         public override void Write(byte[] buffer, int offset, int count) =>
             WriteAsync(buffer, offset, count).GetAwaiter().GetResult();
index 8f50a32..4047a77 100644 (file)
@@ -24,8 +24,6 @@
     <Compile Include="System\IO\Pipes\PipeTransmissionMode.cs" />
     <Compile Include="$(CommonPath)DisableRuntimeMarshalling.cs"
              Link="Common\DisableRuntimeMarshalling.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="Common\System\Threading\Tasks\TaskToApm.cs" />
   </ItemGroup>
 
   <ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'windows'">
index a0652e7..069ff0e 100644 (file)
@@ -162,10 +162,10 @@ namespace System.IO.Pipes
         }
 
         public System.IAsyncResult BeginWaitForConnection(AsyncCallback? callback, object? state) =>
-            TaskToApm.Begin(WaitForConnectionAsync(), callback, state);
+            TaskToAsyncResult.Begin(WaitForConnectionAsync(), callback, state);
 
         public void EndWaitForConnection(IAsyncResult asyncResult) =>
-            TaskToApm.End(asyncResult);
+            TaskToAsyncResult.End(asyncResult);
 
         // Server can only connect from Disconnected state
         private void CheckConnectOperationsServer()
index ce0607a..bba2948 100644 (file)
@@ -103,10 +103,10 @@ namespace System.IO.Pipes
         }
 
         public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
-            => TaskToApm.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), callback, state);
+            => TaskToAsyncResult.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), callback, state);
 
         public override int EndRead(IAsyncResult asyncResult)
-            => TaskToApm.End<int>(asyncResult);
+            => TaskToAsyncResult.End<int>(asyncResult);
 
         public override void Write(byte[] buffer, int offset, int count)
         {
@@ -177,10 +177,10 @@ namespace System.IO.Pipes
         }
 
         public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
-            => TaskToApm.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), callback, state);
+            => TaskToAsyncResult.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), callback, state);
 
         public override void EndWrite(IAsyncResult asyncResult)
-            => TaskToApm.End(asyncResult);
+            => TaskToAsyncResult.End(asyncResult);
 
         internal static string GetPipePath(string serverName, string pipeName)
         {
index 229b604..aed30e5 100644 (file)
@@ -109,7 +109,7 @@ namespace System.IO.Pipes
         public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
         {
             if (_isAsync)
-                return TaskToApm.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), callback, state);
+                return TaskToAsyncResult.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), callback, state);
             else
                 return base.BeginRead(buffer, offset, count, callback, state);
         }
@@ -117,7 +117,7 @@ namespace System.IO.Pipes
         public override int EndRead(IAsyncResult asyncResult)
         {
             if (_isAsync)
-                return TaskToApm.End<int>(asyncResult);
+                return TaskToAsyncResult.End<int>(asyncResult);
             else
                 return base.EndRead(asyncResult);
         }
@@ -205,7 +205,7 @@ namespace System.IO.Pipes
         public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
         {
             if (_isAsync)
-                return TaskToApm.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), callback, state);
+                return TaskToAsyncResult.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), callback, state);
             else
                 return base.BeginWrite(buffer, offset, count, callback, state);
         }
@@ -213,7 +213,7 @@ namespace System.IO.Pipes
         public override void EndWrite(IAsyncResult asyncResult)
         {
             if (_isAsync)
-                TaskToApm.End(asyncResult);
+                TaskToAsyncResult.End(asyncResult);
             else
                 base.EndWrite(asyncResult);
         }
index 5797c2c..958fd6b 100644 (file)
@@ -138,8 +138,10 @@ System.IO.Ports.SerialPort</PackageDescription>
              Link="Common\Interop\Unix\Interop.IOErrors.cs" />
     <Compile Include="$(CommonPath)Interop\Unix\Interop.Poll.Structs.cs"
              Link="Common\Interop\Unix\Interop.Poll.Structs.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="Common\System\Threading\Tasks\TaskToApm.cs" />
+  </ItemGroup>
+
+  <ItemGroup Condition="!$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))">
+    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToAsyncResult.cs" Link="Common\System\Threading\Tasks\TaskToAsyncResult.cs" />
   </ItemGroup>
 
   <ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true'">
index 2d22028..b207ac3 100644 (file)
@@ -520,7 +520,7 @@ namespace System.IO.Ports
 
         public override IAsyncResult BeginRead(byte[] array, int offset, int numBytes, AsyncCallback userCallback, object stateObject)
         {
-            return TaskToApm.Begin(ReadAsync(array, offset, numBytes), userCallback, stateObject);
+            return TaskToAsyncResult.Begin(ReadAsync(array, offset, numBytes), userCallback, stateObject);
         }
 
         // Will wait `timeout` miliseconds or until reading or writing is possible
@@ -576,7 +576,7 @@ namespace System.IO.Ports
 
         public override IAsyncResult BeginWrite(byte[] array, int offset, int count, AsyncCallback userCallback, object stateObject)
         {
-            return TaskToApm.Begin(WriteAsync(array, offset, count), userCallback, stateObject);
+            return TaskToAsyncResult.Begin(WriteAsync(array, offset, count), userCallback, stateObject);
         }
 
         public override void EndWrite(IAsyncResult asyncResult)
@@ -586,7 +586,7 @@ namespace System.IO.Ports
         {
             try
             {
-                return TaskToApm.End<int>(asyncResult);
+                return TaskToAsyncResult.End<int>(asyncResult);
             }
             catch (OperationCanceledException)
             {
index c0d66ac..c7286f4 100644 (file)
@@ -61,7 +61,6 @@
     <Compile Include="$(CommonTestPath)System\IO\ConnectedStreams.cs" Link="Common\System\IO\ConnectedStreams.cs" />
     <Compile Include="$(CommonPath)System\Net\MultiArrayBuffer.cs" Link="ProductionCode\Common\System\Net\MultiArrayBuffer.cs" />
     <Compile Include="$(CommonPath)System\Net\StreamBuffer.cs" Link="ProductionCode\Common\System\Net\StreamBuffer.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs" Link="Common\System\Threading\Tasks\TaskToApm.cs" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="$(CommonTestPath)StreamConformanceTests\StreamConformanceTests.csproj" />
index 0ed88b1..639e4a3 100644 (file)
@@ -12,7 +12,6 @@ System.BinaryData</PackageDescription>
   <ItemGroup>
     <Compile Include="System\BinaryData.cs" />
     <Compile Include="$(CommonPath)System\IO\ReadOnlyMemoryStream.cs" Link="Common\System\IO\ReadOnlyMemoryStream.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs" Link="Common\System\Threading\Tasks\TaskToApm.cs" />
     <Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\RequiresUnreferencedCodeAttribute.cs" Condition="'$(TargetFrameworkIdentifier)' != '.NETCoreApp'" />
     <Compile Include="System\BinaryDataConverter.cs" />
   </ItemGroup>
@@ -20,6 +19,10 @@ System.BinaryData</PackageDescription>
   <ItemGroup Condition="!$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net7.0'))">
     <Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\RequiresDynamicCodeAttribute.cs" />
   </ItemGroup>
+
+  <ItemGroup Condition="!$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))">
+    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToAsyncResult.cs" Link="Common\System\Threading\Tasks\TaskToAsyncResult.cs" />
+  </ItemGroup>
   
   <ItemGroup>
     <ProjectReference Include="$(LibrariesProjectRoot)System.Text.Json\src\System.Text.Json.csproj" />
index 3921f51..e6dd2f5 100644 (file)
@@ -79,8 +79,6 @@ System.Net.Http.WinHttpHandler</PackageDescription>
              Link="Common\System\Runtime\ExceptionServices\ExceptionStackTrace.cs" />
     <Compile Include="$(CommonPath)\System\Threading\Tasks\RendezvousAwaitable.cs"
              Link="Common\System\Threading\Tasks\RendezvousAwaitable.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="Common\System\Threading\Tasks\TaskToApm.cs" />
     <Compile Include="System\Net\Http\NetEventSource.WinHttpHandler.cs" />
     <Compile Include="System\Net\Http\NoWriteNoSeekStreamContent.cs" />
     <Compile Include="System\Net\Http\WinHttpAuthHelper.cs" />
@@ -112,6 +110,10 @@ System.Net.Http.WinHttpHandler</PackageDescription>
              Link="Common\DisableRuntimeMarshalling.cs" />
   </ItemGroup>
 
+  <ItemGroup Condition="!$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))">
+    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToAsyncResult.cs" Link="Common\System\Threading\Tasks\TaskToAsyncResult.cs" />
+  </ItemGroup>
+
   <ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'">
     <PackageReference Include="System.Buffers" Version="$(SystemBuffersVersion)" />
     <PackageReference Include="System.Memory" Version="$(SystemMemoryVersion)" />
index c50f09b..ebbb43e 100644 (file)
@@ -143,10 +143,10 @@ namespace System.Net.Http
         }
 
         public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState) =>
-            TaskToApm.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
+            TaskToAsyncResult.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
 
         public override void EndWrite(IAsyncResult asyncResult) =>
-            TaskToApm.End(asyncResult);
+            TaskToAsyncResult.End(asyncResult);
 
         public override long Seek(long offset, SeekOrigin origin)
         {
index fd0bfee..dccbaea 100644 (file)
@@ -210,10 +210,10 @@ namespace System.Net.Http
         }
 
         public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) =>
-            TaskToApm.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), callback, state);
+            TaskToAsyncResult.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), callback, state);
 
         public override int EndRead(IAsyncResult asyncResult) =>
-            TaskToApm.End<int>(asyncResult);
+            TaskToAsyncResult.End<int>(asyncResult);
 
         private async Task<int> ReadAsyncCore(byte[] buffer, int offset, int count, CancellationToken token)
         {
index 739f32d..791b003 100644 (file)
@@ -57,8 +57,6 @@
              Link="Common\System\Text\SimpleRegex.cs" />
     <Compile Include="$(CommonPath)System\Threading\Tasks\RendezvousAwaitable.cs"
              Link="Common\System\Threading\Tasks\RendezvousAwaitable.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="Common\System\Threading\Tasks\TaskToApm.cs" />
     <Compile Include="..\..\src\System\Net\Http\NoWriteNoSeekStreamContent.cs"
              Link="ProductionCode\NoWriteNoSeekStreamContent.cs" />
     <Compile Include="..\..\src\System\Net\Http\WinHttpAuthHelper.cs"
index df1d8e0..a88b645 100644 (file)
              Link="Common\System\Net\Security\CertificateHelper.Windows.cs" />
     <Compile Include="$(CommonPath)\System\Runtime\ExceptionServices\ExceptionStackTrace.cs"
              Link="Common\System\Runtime\ExceptionServices\ExceptionStackTrace.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="Common\System\Threading\Tasks\TaskToApm.cs" />
   </ItemGroup>
   <ItemGroup Condition="'$(TargetPlatformIdentifier)' != '' and '$(TargetPlatformIdentifier)' != 'windows' and '$(TargetPlatformIdentifier)' != 'browser'">
     <Compile Include="$(CommonPath)System\StrongToWeakReference.cs"
              Link="Common\System\Net\Security\CertificateHelper.cs" />
     <Compile Include="$(CommonPath)System\Net\Security\CertificateHelper.Unix.cs"
              Link="Common\System\Net\Security\CertificateHelper.Unix.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="Common\System\Threading\Tasks\TaskToApm.cs" />
   </ItemGroup>
   <ItemGroup Condition="'$(TargetPlatformIdentifier)' != '' and '$(TargetPlatformIdentifier)' != 'windows' and '$(TargetPlatformIdentifier)' != 'browser' and '$(TargetPlatformIdentifier)' != 'osx' and '$(TargetPlatformIdentifier)' != 'ios' and '$(TargetPlatformIdentifier)' != 'tvos'">
     <Compile Include="$(CommonPath)Interop\Unix\System.Security.Cryptography.Native\Interop.Initialization.cs"
              Link="Common\System\StringExtensions.cs" />
     <Compile Include="$(CommonPath)\System\Net\HttpStatusDescription.cs"
              Link="Common\System\Net\HttpStatusDescription.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="System\System\Threading\Tasks\TaskToApm.cs" />
     <Compile Include="System\Net\Http\SocketsHttpHandler\HttpKeepAlivePingPolicy.cs" />
     <Compile Include="System\Net\Http\SocketsHttpHandler\HttpNoProxy.cs" />
     <Compile Include="System\Net\Http\SocketsHttpHandler\SocketsHttpConnectionContext.cs" />
index 0bcc913..1d90cd6 100644 (file)
@@ -13,16 +13,16 @@ namespace System.Net.Http
         public sealed override bool CanSeek => false;
 
         public sealed override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) =>
-            TaskToApm.Begin(ReadAsync(buffer, offset, count, default), callback, state);
+            TaskToAsyncResult.Begin(ReadAsync(buffer, offset, count, default), callback, state);
 
         public sealed override int EndRead(IAsyncResult asyncResult) =>
-            TaskToApm.End<int>(asyncResult);
+            TaskToAsyncResult.End<int>(asyncResult);
 
         public sealed override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) =>
-            TaskToApm.Begin(WriteAsync(buffer, offset, count, default), callback, state);
+            TaskToAsyncResult.Begin(WriteAsync(buffer, offset, count, default), callback, state);
 
         public sealed override void EndWrite(IAsyncResult asyncResult) =>
-            TaskToApm.End(asyncResult);
+            TaskToAsyncResult.End(asyncResult);
 
         public sealed override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
 
index 4fa0beb..13e4122 100644 (file)
@@ -1031,10 +1031,10 @@ namespace System.Net.Http
             }
 
             public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState) =>
-                TaskToApm.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
+                TaskToAsyncResult.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
 
             public override void EndWrite(IAsyncResult asyncResult) =>
-                TaskToApm.End(asyncResult);
+                TaskToAsyncResult.End(asyncResult);
 
             public override void WriteByte(byte value)
             {
index eb7893a..156abcc 100644 (file)
@@ -533,10 +533,10 @@ namespace System.Net.Http
                 ReadAsyncPrivate(buffer, cancellationToken);
 
             public override IAsyncResult BeginRead(byte[] array, int offset, int count, AsyncCallback? asyncCallback, object? asyncState) =>
-                TaskToApm.Begin(ReadAsync(array, offset, count, CancellationToken.None), asyncCallback, asyncState);
+                TaskToAsyncResult.Begin(ReadAsync(array, offset, count, CancellationToken.None), asyncCallback, asyncState);
 
             public override int EndRead(IAsyncResult asyncResult) =>
-                TaskToApm.End<int>(asyncResult);
+                TaskToAsyncResult.End<int>(asyncResult);
 
             public async ValueTask<int> ReadAsyncPrivate(Memory<byte> buffer, CancellationToken cancellationToken)
             {
index 90c828e..f09fad6 100644 (file)
@@ -45,8 +45,6 @@
              Link="Common\Interop\Unix\Interop.Libraries.cs" />
     <Compile Include="$(CommonPath)System\Net\Logging\NetEventSource.Common.cs"
              Link="Common\System\Net\Logging\NetEventSource.Common.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="System\System\Threading\Tasks\TaskToApm.cs" />
     <Compile Include="$(CommonPath)Interop\Unix\System.Net.Security.Native\Interop.NetSecurityNative.IsNtlmInstalled.cs" Condition="'$(TargetPlatformIdentifier)' != 'windows'"
              Link="Common\Interop\Unix\System.Net.Security.Native\Interop.NetSecurityNative.IsNtlmInstalled.cs" />
     <Compile Include="$(CommonTestPath)System\Buffers\NativeMemoryManager.cs"
index 0ce0955..4240962 100644 (file)
@@ -54,8 +54,6 @@
              Link="Common\System\Net\Http\HPackEncoder.cs" />
     <Compile Include="$(CommonTestPath)System\Net\Http\HuffmanEncoder.cs"
              Link="Common\System\Net\Http\HuffmanEncoder.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="ProductionCode\Common\System\Threading\Tasks\TaskToApm.cs" />
     <Compile Include="..\..\src\System\Net\Http\SocketsHttpHandler\AuthenticationHelper.Digest.cs"
              Link="ProductionCode\System\Net\Http\SocketsHttpHandler\AuthenticationHelper.Digest.cs" />
     <Compile Include="..\..\src\System\Net\Http\SocketsHttpHandler\HttpKeepAlivePingPolicy.cs"
index 7464272..49106b9 100644 (file)
     <Compile Include="System\Net\Managed\ChunkStream.cs" />
     <Compile Include="System\Net\Managed\HttpResponseStream.Managed.cs" />
     <Compile Include="System\Net\Managed\WebSockets\HttpWebSocket.Managed.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="Common\System\Threading\Tasks\TaskToApm.cs" />
     <Reference Include="System.Net.Sockets" />
     <Reference Include="System.Net.ServicePoint" />
     <Reference Include="System.Threading.ThreadPool" />
index 127119d..254be8e 100644 (file)
@@ -19,8 +19,6 @@
              Link="Common\System\Net\Logging\NetEventSource.Common.cs" />
     <Compile Include="$(CommonPath)System\Net\InternalException.cs"
              Link="Common\System\Net\InternalException.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="Common\System\Threading\Tasks\TaskToApm.cs" />
     <!-- System.Net common -->
     <Compile Include="$(CommonPath)System\Net\Sockets\ProtocolType.cs"
              Link="Common\System\Net\Sockets\ProtocolType.cs" />
index cf049da..0ee39a3 100644 (file)
@@ -164,16 +164,16 @@ namespace System.Net
         }
 
         public static IAsyncResult BeginGetHostEntry(IPAddress address, AsyncCallback? requestCallback, object? stateObject) =>
-            TaskToApm.Begin(GetHostEntryAsync(address), requestCallback, stateObject);
+            TaskToAsyncResult.Begin(GetHostEntryAsync(address), requestCallback, stateObject);
 
         public static IAsyncResult BeginGetHostEntry(string hostNameOrAddress, AsyncCallback? requestCallback, object? stateObject) =>
-            TaskToApm.Begin(GetHostEntryAsync(hostNameOrAddress), requestCallback, stateObject);
+            TaskToAsyncResult.Begin(GetHostEntryAsync(hostNameOrAddress), requestCallback, stateObject);
 
         public static IPHostEntry EndGetHostEntry(IAsyncResult asyncResult)
         {
             ArgumentNullException.ThrowIfNull(asyncResult);
 
-            return TaskToApm.End<IPHostEntry>(asyncResult);
+            return TaskToAsyncResult.End<IPHostEntry>(asyncResult);
         }
 
         public static IPAddress[] GetHostAddresses(string hostNameOrAddress)
@@ -241,13 +241,13 @@ namespace System.Net
             (Task<IPAddress[]>)GetHostEntryOrAddressesCoreAsync(hostNameOrAddress, justReturnParsedIp: true, throwOnIIPAny: true, justAddresses: true, family, cancellationToken);
 
         public static IAsyncResult BeginGetHostAddresses(string hostNameOrAddress, AsyncCallback? requestCallback, object? state) =>
-            TaskToApm.Begin(GetHostAddressesAsync(hostNameOrAddress), requestCallback, state);
+            TaskToAsyncResult.Begin(GetHostAddressesAsync(hostNameOrAddress), requestCallback, state);
 
         public static IPAddress[] EndGetHostAddresses(IAsyncResult asyncResult)
         {
             ArgumentNullException.ThrowIfNull(asyncResult);
 
-            return TaskToApm.End<IPAddress[]>(asyncResult);
+            return TaskToAsyncResult.End<IPAddress[]>(asyncResult);
         }
 
         [Obsolete("GetHostByName has been deprecated. Use GetHostEntry instead.")]
@@ -265,14 +265,14 @@ namespace System.Net
 
         [Obsolete("BeginGetHostByName has been deprecated. Use BeginGetHostEntry instead.")]
         public static IAsyncResult BeginGetHostByName(string hostName, AsyncCallback? requestCallback, object? stateObject) =>
-            TaskToApm.Begin(GetHostEntryCoreAsync(hostName, justReturnParsedIp: true, throwOnIIPAny: true, AddressFamily.Unspecified, CancellationToken.None), requestCallback, stateObject);
+            TaskToAsyncResult.Begin(GetHostEntryCoreAsync(hostName, justReturnParsedIp: true, throwOnIIPAny: true, AddressFamily.Unspecified, CancellationToken.None), requestCallback, stateObject);
 
         [Obsolete("EndGetHostByName has been deprecated. Use EndGetHostEntry instead.")]
         public static IPHostEntry EndGetHostByName(IAsyncResult asyncResult)
         {
             ArgumentNullException.ThrowIfNull(asyncResult);
 
-            return TaskToApm.End<IPHostEntry>(asyncResult);
+            return TaskToAsyncResult.End<IPHostEntry>(asyncResult);
         }
 
         [Obsolete("GetHostByAddress has been deprecated. Use GetHostEntry instead.")]
@@ -328,7 +328,7 @@ namespace System.Net
 
         [Obsolete("BeginResolve has been deprecated. Use BeginGetHostEntry instead.")]
         public static IAsyncResult BeginResolve(string hostName, AsyncCallback? requestCallback, object? stateObject) =>
-            TaskToApm.Begin(GetHostEntryCoreAsync(hostName, justReturnParsedIp: false, throwOnIIPAny: false, AddressFamily.Unspecified, CancellationToken.None), requestCallback, stateObject);
+            TaskToAsyncResult.Begin(GetHostEntryCoreAsync(hostName, justReturnParsedIp: false, throwOnIIPAny: false, AddressFamily.Unspecified, CancellationToken.None), requestCallback, stateObject);
 
         [Obsolete("EndResolve has been deprecated. Use EndGetHostEntry instead.")]
         public static IPHostEntry EndResolve(IAsyncResult asyncResult)
@@ -337,16 +337,11 @@ namespace System.Net
 
             try
             {
-                ipHostEntry = TaskToApm.End<IPHostEntry>(asyncResult);
+                ipHostEntry = TaskToAsyncResult.End<IPHostEntry>(asyncResult);
             }
             catch (SocketException ex)
             {
-                object? asyncState = asyncResult switch
-                {
-                    Task t => t.AsyncState,
-                    TaskToApm.TaskAsyncResult twar => twar._task.AsyncState,
-                    _ => null
-                };
+                object? asyncState = TaskToAsyncResult.Unwrap(asyncResult).AsyncState;
 
                 IPAddress? address = asyncState switch
                 {
index e8621ab..c9b2bbb 100644 (file)
@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <TargetFrameworks>$(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-linux;$(NetCoreAppCurrent)-android;$(NetCoreAppCurrent)-osx;$(NetCoreAppCurrent)-ios;$(NetCoreAppCurrent)-tvos;$(NetCoreAppCurrent)-freebsd;$(NetCoreAppCurrent)-illumos;$(NetCoreAppCurrent)-solaris;$(NetCoreAppCurrent)</TargetFrameworks>
@@ -51,7 +51,6 @@
     <Compile Include="$(CommonPath)System\Net\NetworkInformation\HostInformation.cs" Link="Common\System\Net\NetworkInformation\HostInformation.cs" />
     <Compile Include="$(CommonPath)System\Net\NetworkInformation\NetworkInformationException.cs" Link="Common\System\Net\NetworkInformation\NetworkInformationException.cs" />
     <Compile Include="$(CommonPath)System\HexConverter.cs" Link="Common\System\HexConverter.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs" Link="Common\System\Threading\Tasks\TaskToApm.cs" />
   </ItemGroup>
   <ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'windows'">
     <!-- Interop -->
index b460cef..3090e47 100644 (file)
@@ -368,10 +368,10 @@ namespace System.Net.NetworkInformation
         }
 
         public override IAsyncResult BeginGetUnicastAddresses(AsyncCallback? callback, object? state) =>
-            TaskToApm.Begin(GetUnicastAddressesAsync(), callback, state);
+            TaskToAsyncResult.Begin(GetUnicastAddressesAsync(), callback, state);
 
         public override UnicastIPAddressInformationCollection EndGetUnicastAddresses(IAsyncResult asyncResult) =>
-            TaskToApm.End<UnicastIPAddressInformationCollection>(asyncResult);
+            TaskToAsyncResult.End<UnicastIPAddressInformationCollection>(asyncResult);
 
         public override UnicastIPAddressInformationCollection GetUnicastAddresses() =>
             GetUnicastAddressesAsync().GetAwaiter().GetResult();
index 9de6b8b..f26aa57 100644 (file)
@@ -43,12 +43,12 @@ namespace System.Net.NetworkInformation
         public override IAsyncResult BeginGetUnicastAddresses(AsyncCallback? callback, object? state)
         {
             Task<UnicastIPAddressInformationCollection> t = GetUnicastAddressesAsync();
-            return TaskToApm.Begin(t, callback, state);
+            return TaskToAsyncResult.Begin(t, callback, state);
         }
 
         public override UnicastIPAddressInformationCollection EndGetUnicastAddresses(IAsyncResult asyncResult)
         {
-            return TaskToApm.End<UnicastIPAddressInformationCollection>(asyncResult);
+            return TaskToAsyncResult.End<UnicastIPAddressInformationCollection>(asyncResult);
         }
 
         public sealed override Task<UnicastIPAddressInformationCollection> GetUnicastAddressesAsync()
index b7b6b7e..ebbed23 100644 (file)
@@ -22,7 +22,6 @@
     <Compile Include="System\Net\Quic\**\*.cs" Exclude="System\Net\Quic\*.Unsupported.cs"/>
     <!-- System.Net common -->
     <Compile Include="$(CommonPath)DisableRuntimeMarshalling.cs" Link="Common\DisableRuntimeMarshalling.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs" Link="Common\System\Threading\Tasks\TaskToApm.cs" />
     <Compile Include="$(CommonPath)System\Net\ArrayBuffer.cs" Link="Common\System\Net\ArrayBuffer.cs" />
     <Compile Include="$(CommonPath)System\Net\MultiArrayBuffer.cs" Link="Common\System\Net\MultiArrayBuffer.cs" />
     <Compile Include="$(CommonPath)System\Net\Logging\NetEventSource.Common.cs" Link="Common\System\Net\Logging\NetEventSource.Common.cs" />
index 8bf9799..dd6fa5a 100644 (file)
@@ -90,11 +90,11 @@ public partial class QuicStream : Stream
 
     /// <inheritdoc />
     public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
-        => TaskToApm.Begin(ReadAsync(buffer, offset, count, default), callback, state);
+        => TaskToAsyncResult.Begin(ReadAsync(buffer, offset, count, default), callback, state);
 
     /// <inheritdoc />
     public override int EndRead(IAsyncResult asyncResult)
-        => TaskToApm.End<int>(asyncResult);
+        => TaskToAsyncResult.End<int>(asyncResult);
 
     /// <inheritdoc />
     public override int Read(byte[] buffer, int offset, int count)
@@ -153,11 +153,11 @@ public partial class QuicStream : Stream
 
     /// <inheritdoc />
     public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
-        => TaskToApm.Begin(WriteAsync(buffer, offset, count, default), callback, state);
+        => TaskToAsyncResult.Begin(WriteAsync(buffer, offset, count, default), callback, state);
 
     /// <inheritdoc />
     public override void EndWrite(IAsyncResult asyncResult)
-        => TaskToApm.End(asyncResult);
+        => TaskToAsyncResult.End(asyncResult);
 
     /// <inheritdoc />
     public override void Write(byte[] buffer, int offset, int count)
index c088044..2b31dee 100644 (file)
@@ -16,7 +16,6 @@
     <Compile Include="$(CommonPath)System\Net\ArrayBuffer.cs" Link="ProductionCode\Common\System\Net\ArrayBuffer.cs" />
     <Compile Include="$(CommonPath)System\Net\MultiArrayBuffer.cs" Link="ProductionCode\Common\System\Net\MultiArrayBuffer.cs" />
     <Compile Include="$(CommonPath)System\Net\StreamBuffer.cs" Link="ProductionCode\Common\System\Net\StreamBuffer.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs" Link="Common\System\Threading\Tasks\TaskToApm.cs" />
     <Compile Include="$(CommonTestPath)System\IO\ConnectedStreams.cs" Link="Common\System\IO\ConnectedStreams.cs" />
     <Compile Include="$(CommonTestPath)System\Net\Capability.Security.cs" Link="Common\System\Net\Capability.Security.cs" />
     <Compile Include="$(CommonTestPath)System\Net\Configuration.cs" Link="Common\System\Net\Configuration.cs" />
index 051c2bc..505dc8a 100644 (file)
@@ -76,8 +76,6 @@
              Link="Common\System\Net\SecurityProtocol.cs" />
     <Compile Include="$(CommonPath)System\NotImplemented.cs"
              Link="Common\System\NotImplemented.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="Common\System\Threading\Tasks\TaskToApm.cs" />
   </ItemGroup>
   <ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'windows'">
     <Compile Include="$(CommonPath)Interop\Windows\WinInet\Interop.wininet_errors.cs"
index cfbea34..42a7f41 100644 (file)
@@ -158,7 +158,7 @@ namespace System.Net
             CheckAndMarkAsyncGetRequestStreamPending();
             Task<Stream> t = Task.Factory.StartNew<Stream>(s => ((FileWebRequest)s!).CreateWriteStream(),
                 this, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
-            return TaskToApm.Begin(t, callback, state);
+            return TaskToAsyncResult.Begin(t, callback, state);
         }
 
         public override Task<Stream> GetRequestStreamAsync()
@@ -219,7 +219,7 @@ namespace System.Net
             CheckAndMarkAsyncGetResponsePending();
             Task<WebResponse> t = Task.Factory.StartNew(s => ((FileWebRequest)s!).CreateResponse(),
                  this, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
-            return TaskToApm.Begin(t, callback, state);
+            return TaskToAsyncResult.Begin(t, callback, state);
         }
 
         public override Task<WebResponse> GetResponseAsync()
@@ -236,14 +236,14 @@ namespace System.Net
 
         public override Stream EndGetRequestStream(IAsyncResult asyncResult)
         {
-            Stream stream = TaskToApm.End<Stream>(asyncResult);
+            Stream stream = TaskToAsyncResult.End<Stream>(asyncResult);
             _writePending = false;
             return stream;
         }
 
         public override WebResponse EndGetResponse(IAsyncResult asyncResult)
         {
-            WebResponse response = TaskToApm.End<WebResponse>(asyncResult);
+            WebResponse response = TaskToAsyncResult.End<WebResponse>(asyncResult);
             _readPending = false;
             return response;
         }
index bc44d7a..b594f3f 100644 (file)
@@ -90,8 +90,6 @@
     <!-- Common -->
     <Compile Include="$(CommonPath)System\NotImplemented.cs"
              Link="Common\System\NotImplemented.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="Common\System\Threading\Tasks\TaskToApm.cs" />
     <Compile Include="$(CommonPath)System\Net\Security\TlsAlertMessage.cs"
              Link="Common\System\Net\Security\TlsAlertMessage.cs" />
     <Compile Include="$(CommonPath)System\Net\Security\SafeCredentialReference.cs"
index 67bc7b4..efed209 100644 (file)
@@ -116,9 +116,9 @@ namespace System.Net.Security
         public virtual IAsyncResult BeginAuthenticateAsClient(
             NetworkCredential credential, ChannelBinding? binding, string targetName, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel allowedImpersonationLevel,
             AsyncCallback? asyncCallback, object? asyncState) =>
-            TaskToApm.Begin(AuthenticateAsClientAsync(credential, binding, targetName, requiredProtectionLevel, allowedImpersonationLevel), asyncCallback, asyncState);
+            TaskToAsyncResult.Begin(AuthenticateAsClientAsync(credential, binding, targetName, requiredProtectionLevel, allowedImpersonationLevel), asyncCallback, asyncState);
 
-        public virtual void EndAuthenticateAsClient(IAsyncResult asyncResult) => TaskToApm.End(asyncResult);
+        public virtual void EndAuthenticateAsClient(IAsyncResult asyncResult) => TaskToAsyncResult.End(asyncResult);
 
         public virtual void AuthenticateAsServer() =>
             AuthenticateAsServer((NetworkCredential)CredentialCache.DefaultCredentials, policy: null, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification);
@@ -149,9 +149,9 @@ namespace System.Net.Security
         public virtual IAsyncResult BeginAuthenticateAsServer(
             NetworkCredential credential, ExtendedProtectionPolicy? policy, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel requiredImpersonationLevel,
             AsyncCallback? asyncCallback, object? asyncState) =>
-            TaskToApm.Begin(AuthenticateAsServerAsync(credential, policy, requiredProtectionLevel, requiredImpersonationLevel), asyncCallback, asyncState);
+            TaskToAsyncResult.Begin(AuthenticateAsServerAsync(credential, policy, requiredProtectionLevel, requiredImpersonationLevel), asyncCallback, asyncState);
 
-        public virtual void EndAuthenticateAsServer(IAsyncResult asyncResult) => TaskToApm.End(asyncResult);
+        public virtual void EndAuthenticateAsServer(IAsyncResult asyncResult) => TaskToAsyncResult.End(asyncResult);
 
         public virtual void AuthenticateAsClient() =>
             AuthenticateAsClient((NetworkCredential)CredentialCache.DefaultCredentials, binding: null, string.Empty, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification);
@@ -518,16 +518,16 @@ namespace System.Net.Security
         }
 
         public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState) =>
-            TaskToApm.Begin(ReadAsync(buffer, offset, count), asyncCallback, asyncState);
+            TaskToAsyncResult.Begin(ReadAsync(buffer, offset, count), asyncCallback, asyncState);
 
         public override int EndRead(IAsyncResult asyncResult) =>
-            TaskToApm.End<int>(asyncResult);
+            TaskToAsyncResult.End<int>(asyncResult);
 
         public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState) =>
-            TaskToApm.Begin(WriteAsync(buffer, offset, count), asyncCallback, asyncState);
+            TaskToAsyncResult.Begin(WriteAsync(buffer, offset, count), asyncCallback, asyncState);
 
         public override void EndWrite(IAsyncResult asyncResult) =>
-            TaskToApm.End(asyncResult);
+            TaskToAsyncResult.End(asyncResult);
 
         private void ThrowIfExceptional()
         {
index a086fc9..9f4ac13 100644 (file)
@@ -248,9 +248,9 @@ namespace System.Net.Security
         }
 
         internal IAsyncResult BeginAuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthenticationOptions, CancellationToken cancellationToken, AsyncCallback? asyncCallback, object? asyncState) =>
-            TaskToApm.Begin(AuthenticateAsClientAsync(sslClientAuthenticationOptions, cancellationToken)!, asyncCallback, asyncState);
+            TaskToAsyncResult.Begin(AuthenticateAsClientAsync(sslClientAuthenticationOptions, cancellationToken)!, asyncCallback, asyncState);
 
-        public virtual void EndAuthenticateAsClient(IAsyncResult asyncResult) => TaskToApm.End(asyncResult);
+        public virtual void EndAuthenticateAsClient(IAsyncResult asyncResult) => TaskToAsyncResult.End(asyncResult);
 
         //
         // Server side auth.
@@ -287,13 +287,13 @@ namespace System.Net.Security
         }
 
         private IAsyncResult BeginAuthenticateAsServer(SslServerAuthenticationOptions sslServerAuthenticationOptions, CancellationToken cancellationToken, AsyncCallback? asyncCallback, object? asyncState) =>
-            TaskToApm.Begin(AuthenticateAsServerAsync(sslServerAuthenticationOptions, cancellationToken)!, asyncCallback, asyncState);
+            TaskToAsyncResult.Begin(AuthenticateAsServerAsync(sslServerAuthenticationOptions, cancellationToken)!, asyncCallback, asyncState);
 
-        public virtual void EndAuthenticateAsServer(IAsyncResult asyncResult) => TaskToApm.End(asyncResult);
+        public virtual void EndAuthenticateAsServer(IAsyncResult asyncResult) => TaskToAsyncResult.End(asyncResult);
 
-        internal IAsyncResult BeginShutdown(AsyncCallback? asyncCallback, object? asyncState) => TaskToApm.Begin(ShutdownAsync(), asyncCallback, asyncState);
+        internal IAsyncResult BeginShutdown(AsyncCallback? asyncCallback, object? asyncState) => TaskToAsyncResult.Begin(ShutdownAsync(), asyncCallback, asyncState);
 
-        internal static void EndShutdown(IAsyncResult asyncResult) => TaskToApm.End(asyncResult);
+        internal static void EndShutdown(IAsyncResult asyncResult) => TaskToAsyncResult.End(asyncResult);
 
         public TransportContext TransportContext => new SslStreamContext(this);
 
@@ -767,25 +767,25 @@ namespace System.Net.Security
         public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState)
         {
             ThrowIfExceptionalOrNotAuthenticated();
-            return TaskToApm.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
+            return TaskToAsyncResult.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
         }
 
         public override int EndRead(IAsyncResult asyncResult)
         {
             ThrowIfExceptionalOrNotAuthenticated();
-            return TaskToApm.End<int>(asyncResult);
+            return TaskToAsyncResult.End<int>(asyncResult);
         }
 
         public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState)
         {
             ThrowIfExceptionalOrNotAuthenticated();
-            return TaskToApm.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
+            return TaskToAsyncResult.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
         }
 
         public override void EndWrite(IAsyncResult asyncResult)
         {
             ThrowIfExceptionalOrNotAuthenticated();
-            TaskToApm.End(asyncResult);
+            TaskToAsyncResult.End(asyncResult);
         }
 
         public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
index 809f2f3..3714c1b 100644 (file)
@@ -19,7 +19,5 @@
              Link="Common\System\Net\EnterpriseTests\EnterpriseTestConfiguration.cs" />
     <Compile Include="$(CommonTestPath)System\Threading\Tasks\TaskTimeoutExtensions.cs"
              Link="Common\System\Threading\Tasks\TaskTimeoutExtensions.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="ProductionCode\Common\System\Threading\Tasks\TaskToApm.cs" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
index 56e1f32..0db9e97 100644 (file)
@@ -91,8 +91,6 @@
              Link="CommonTest\System\Security\Cryptography\X509Certificates\RevocationResponder.cs" />
     <Compile Include="$(CommonTestPath)System\Threading\Tasks\TaskTimeoutExtensions.cs"
              Link="Common\System\Threading\Tasks\TaskTimeoutExtensions.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="ProductionCode\Common\System\Threading\Tasks\TaskToApm.cs" />
     <Compile Include="$(CommonPath)System\IO\DelegatingStream.cs"
              Link="ProductionCode\Common\System\IO\DelegatingStream.cs" />
     <Compile Include="$(CommonPath)System\Net\ArrayBuffer.cs"
diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/result.txt b/src/libraries/System.Net.Security/tests/FunctionalTests/result.txt
deleted file mode 100644 (file)
index 5f1162d..0000000
Binary files a/src/libraries/System.Net.Security/tests/FunctionalTests/result.txt and /dev/null differ
index 2a2655a..6618a8d 100644 (file)
@@ -80,8 +80,6 @@
              Link="ProductionCode\Common\System\Net\TlsFrameHelper.cs" />
     <Compile Include="$(CommonPath)Interop\Windows\SChannel\Interop.Alerts.cs"
              Link="Common\Interop\Windows\SChannel\Interop.Alerts.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="Common\System\Threading\Tasks\TaskToApm.cs" />
     <Compile Include="$(CommonPath)System\Obsoletions.cs" 
              Link="Common\System\Obsoletions.cs" />
     <!-- IP parser -->
index e50db90..457d891 100644 (file)
@@ -73,8 +73,6 @@
              Link="Common\System\Net\TcpValidationHelpers.cs" />
     <Compile Include="$(CommonPath)System\Net\SocketProtocolSupportPal.cs"
              Link="Common\System\Net\SocketProtocolSupportPal.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="Common\System\Threading\Tasks\TaskToApm.cs" />
     <!-- System.Net.Internals -->
     <Compile Include="$(CommonPath)System\Net\Internals\IPEndPointExtensions.cs"
              Link="Common\System\Net\Internals\IPEndPointExtensions.cs" />
index 8aa270f..6c10d2c 100644 (file)
@@ -2236,21 +2236,21 @@ namespace System.Net.Sockets
         }
 
         public IAsyncResult BeginConnect(EndPoint remoteEP, AsyncCallback? callback, object? state) =>
-            TaskToApm.Begin(ConnectAsync(remoteEP), callback, state);
+            TaskToAsyncResult.Begin(ConnectAsync(remoteEP), callback, state);
 
         public IAsyncResult BeginConnect(string host, int port, AsyncCallback? requestCallback, object? state) =>
-            TaskToApm.Begin(ConnectAsync(host, port), requestCallback, state);
+            TaskToAsyncResult.Begin(ConnectAsync(host, port), requestCallback, state);
 
         public IAsyncResult BeginConnect(IPAddress address, int port, AsyncCallback? requestCallback, object? state) =>
-            TaskToApm.Begin(ConnectAsync(address, port), requestCallback, state);
+            TaskToAsyncResult.Begin(ConnectAsync(address, port), requestCallback, state);
 
         public IAsyncResult BeginConnect(IPAddress[] addresses, int port, AsyncCallback? requestCallback, object? state) =>
-            TaskToApm.Begin(ConnectAsync(addresses, port), requestCallback, state);
+            TaskToAsyncResult.Begin(ConnectAsync(addresses, port), requestCallback, state);
 
-        public void EndConnect(IAsyncResult asyncResult) => TaskToApm.End(asyncResult);
+        public void EndConnect(IAsyncResult asyncResult) => TaskToAsyncResult.End(asyncResult);
 
         public IAsyncResult BeginDisconnect(bool reuseSocket, AsyncCallback? callback, object? state) =>
-            TaskToApm.Begin(DisconnectAsync(reuseSocket).AsTask(), callback, state);
+            TaskToAsyncResult.Begin(DisconnectAsync(reuseSocket).AsTask(), callback, state);
 
         public void Disconnect(bool reuseSocket)
         {
@@ -2273,14 +2273,14 @@ namespace System.Net.Sockets
             _localEndPoint = null;
         }
 
-        public void EndDisconnect(IAsyncResult asyncResult) => TaskToApm.End(asyncResult);
+        public void EndDisconnect(IAsyncResult asyncResult) => TaskToAsyncResult.End(asyncResult);
 
         public IAsyncResult BeginSend(byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback? callback, object? state)
         {
             ThrowIfDisposed();
             ValidateBufferArguments(buffer, offset, size);
 
-            return TaskToApm.Begin(SendAsync(new ReadOnlyMemory<byte>(buffer, offset, size), socketFlags, default).AsTask(), callback, state);
+            return TaskToAsyncResult.Begin(SendAsync(new ReadOnlyMemory<byte>(buffer, offset, size), socketFlags, default).AsTask(), callback, state);
         }
 
         public IAsyncResult? BeginSend(byte[] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode, AsyncCallback? callback, object? state)
@@ -2296,14 +2296,14 @@ namespace System.Net.Sockets
             }
 
             errorCode = SocketError.Success;
-            return TaskToApm.Begin(t, callback, state);
+            return TaskToAsyncResult.Begin(t, callback, state);
         }
 
         public IAsyncResult BeginSend(IList<ArraySegment<byte>> buffers, SocketFlags socketFlags, AsyncCallback? callback, object? state)
         {
             ThrowIfDisposed();
 
-            return TaskToApm.Begin(SendAsync(buffers, socketFlags), callback, state);
+            return TaskToAsyncResult.Begin(SendAsync(buffers, socketFlags), callback, state);
         }
 
         public IAsyncResult? BeginSend(IList<ArraySegment<byte>> buffers, SocketFlags socketFlags, out SocketError errorCode, AsyncCallback? callback, object? state)
@@ -2318,10 +2318,10 @@ namespace System.Net.Sockets
             }
 
             errorCode = SocketError.Success;
-            return TaskToApm.Begin(t, callback, state);
+            return TaskToAsyncResult.Begin(t, callback, state);
         }
 
-        public int EndSend(IAsyncResult asyncResult) => TaskToApm.End<int>(asyncResult);
+        public int EndSend(IAsyncResult asyncResult) => TaskToAsyncResult.End<int>(asyncResult);
 
         public int EndSend(IAsyncResult asyncResult, out SocketError errorCode) =>
             EndSendReceive(asyncResult, out errorCode);
@@ -2342,10 +2342,10 @@ namespace System.Net.Sockets
 
             if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"::DoBeginSendFile() SRC:{LocalEndPoint} DST:{RemoteEndPoint} fileName:{fileName}");
 
-            return TaskToApm.Begin(SendFileAsync(fileName, preBuffer, postBuffer, flags).AsTask(), callback, state);
+            return TaskToAsyncResult.Begin(SendFileAsync(fileName, preBuffer, postBuffer, flags).AsTask(), callback, state);
         }
 
-        public void EndSendFile(IAsyncResult asyncResult) => TaskToApm.End(asyncResult);
+        public void EndSendFile(IAsyncResult asyncResult) => TaskToAsyncResult.End(asyncResult);
 
         public IAsyncResult BeginSendTo(byte[] buffer, int offset, int size, SocketFlags socketFlags, EndPoint remoteEP, AsyncCallback? callback, object? state)
         {
@@ -2354,16 +2354,16 @@ namespace System.Net.Sockets
             ArgumentNullException.ThrowIfNull(remoteEP);
 
             Task<int> t = SendToAsync(buffer.AsMemory(offset, size), socketFlags, remoteEP).AsTask();
-            return TaskToApm.Begin(t, callback, state);
+            return TaskToAsyncResult.Begin(t, callback, state);
         }
 
-        public int EndSendTo(IAsyncResult asyncResult) => TaskToApm.End<int>(asyncResult);
+        public int EndSendTo(IAsyncResult asyncResult) => TaskToAsyncResult.End<int>(asyncResult);
 
         public IAsyncResult BeginReceive(byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback? callback, object? state)
         {
             ThrowIfDisposed();
             ValidateBufferArguments(buffer, offset, size);
-            return TaskToApm.Begin(ReceiveAsync(new ArraySegment<byte>(buffer, offset, size), socketFlags, fromNetworkStream: false, default).AsTask(), callback, state);
+            return TaskToAsyncResult.Begin(ReceiveAsync(new ArraySegment<byte>(buffer, offset, size), socketFlags, fromNetworkStream: false, default).AsTask(), callback, state);
         }
 
         public IAsyncResult? BeginReceive(byte[] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode, AsyncCallback? callback, object? state)
@@ -2379,13 +2379,13 @@ namespace System.Net.Sockets
             }
 
             errorCode = SocketError.Success;
-            return TaskToApm.Begin(t, callback, state);
+            return TaskToAsyncResult.Begin(t, callback, state);
         }
 
         public IAsyncResult BeginReceive(IList<ArraySegment<byte>> buffers, SocketFlags socketFlags, AsyncCallback? callback, object? state)
         {
             ThrowIfDisposed();
-            return TaskToApm.Begin(ReceiveAsync(buffers, socketFlags), callback, state);
+            return TaskToAsyncResult.Begin(ReceiveAsync(buffers, socketFlags), callback, state);
         }
 
         public IAsyncResult? BeginReceive(IList<ArraySegment<byte>> buffers, SocketFlags socketFlags, out SocketError errorCode, AsyncCallback? callback, object? state)
@@ -2400,21 +2400,17 @@ namespace System.Net.Sockets
             }
 
             errorCode = SocketError.Success;
-            return TaskToApm.Begin(t, callback, state);
+            return TaskToAsyncResult.Begin(t, callback, state);
         }
 
-        public int EndReceive(IAsyncResult asyncResult) => TaskToApm.End<int>(asyncResult);
+        public int EndReceive(IAsyncResult asyncResult) => TaskToAsyncResult.End<int>(asyncResult);
 
         public int EndReceive(IAsyncResult asyncResult, out SocketError errorCode) =>
             EndSendReceive(asyncResult, out errorCode);
 
         private static int EndSendReceive(IAsyncResult asyncResult, out SocketError errorCode)
         {
-            if (TaskToApm.GetTask(asyncResult) is not Task<int> ti)
-            {
-                ArgumentNullException.ThrowIfNull(asyncResult);
-                throw new ArgumentException(null, nameof(asyncResult));
-            }
+            Task<int> ti = TaskToAsyncResult.Unwrap<int>(asyncResult);
 
             if (!ti.IsCompleted)
             {
@@ -2448,7 +2444,7 @@ namespace System.Net.Sockets
                 EndPoint resultEp = t.Result.RemoteEndPoint;
                 if (!remoteEP.Equals(resultEp)) remoteEP = resultEp;
             }
-            IAsyncResult asyncResult = TaskToApm.Begin(t, callback, state);
+            IAsyncResult asyncResult = TaskToAsyncResult.Begin(t, callback, state);
             if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"size:{size} returning AsyncResult:{asyncResult}");
             return asyncResult;
         }
@@ -2461,7 +2457,7 @@ namespace System.Net.Sockets
                 throw new ArgumentException(SR.Format(SR.net_InvalidEndPointAddressFamily, endPoint.AddressFamily, _addressFamily), nameof(endPoint));
             }
 
-            SocketReceiveMessageFromResult result = TaskToApm.End<SocketReceiveMessageFromResult>(asyncResult);
+            SocketReceiveMessageFromResult result = TaskToAsyncResult.End<SocketReceiveMessageFromResult>(asyncResult);
             if (!endPoint.Equals(result.RemoteEndPoint))
             {
                 endPoint = result.RemoteEndPoint;
@@ -2486,7 +2482,7 @@ namespace System.Net.Sockets
                 if (!remoteEP.Equals(resultEp)) remoteEP = resultEp;
             }
 
-            return TaskToApm.Begin(t, callback, state);
+            return TaskToAsyncResult.Begin(t, callback, state);
         }
 
         public int EndReceiveFrom(IAsyncResult asyncResult, ref EndPoint endPoint)
@@ -2497,7 +2493,7 @@ namespace System.Net.Sockets
                 throw new ArgumentException(SR.Format(SR.net_InvalidEndPointAddressFamily, endPoint.AddressFamily, _addressFamily), nameof(endPoint));
             }
 
-            SocketReceiveFromResult result = TaskToApm.End<SocketReceiveFromResult>(asyncResult);
+            SocketReceiveFromResult result = TaskToAsyncResult.End<SocketReceiveFromResult>(asyncResult);
             if (!endPoint.Equals(result.RemoteEndPoint))
             {
                 endPoint = result.RemoteEndPoint;
@@ -2506,9 +2502,9 @@ namespace System.Net.Sockets
         }
 
         public IAsyncResult BeginAccept(AsyncCallback? callback, object? state) =>
-            TaskToApm.Begin(AcceptAsync(), callback, state);
+            TaskToAsyncResult.Begin(AcceptAsync(), callback, state);
 
-        public Socket EndAccept(IAsyncResult asyncResult) => TaskToApm.End<Socket>(asyncResult);
+        public Socket EndAccept(IAsyncResult asyncResult) => TaskToAsyncResult.End<Socket>(asyncResult);
 
         // This method provides support for legacy BeginAccept methods that take a "receiveSize" argument and
         // allow data to be received as part of the accept operation.
@@ -2547,7 +2543,7 @@ namespace System.Net.Sockets
             BeginAccept(acceptSocket: null, receiveSize, callback, state);
 
         public IAsyncResult BeginAccept(Socket? acceptSocket, int receiveSize, AsyncCallback? callback, object? state) =>
-            TaskToApm.Begin(AcceptAndReceiveHelperAsync(acceptSocket, receiveSize), callback, state);
+            TaskToAsyncResult.Begin(AcceptAndReceiveHelperAsync(acceptSocket, receiveSize), callback, state);
 
         public Socket EndAccept(out byte[] buffer, IAsyncResult asyncResult)
         {
@@ -2560,7 +2556,7 @@ namespace System.Net.Sockets
         public Socket EndAccept(out byte[] buffer, out int bytesTransferred, IAsyncResult asyncResult)
         {
             Socket s;
-            (s, buffer, bytesTransferred) = TaskToApm.End<(Socket, byte[], int)>(asyncResult);
+            (s, buffer, bytesTransferred) = TaskToAsyncResult.End<(Socket, byte[], int)>(asyncResult);
             return s;
         }
 
index 6ee9ff7..4cb923f 100644 (file)
@@ -201,13 +201,13 @@ namespace System.Net.Sockets
         }
 
         public IAsyncResult BeginAcceptSocket(AsyncCallback? callback, object? state) =>
-            TaskToApm.Begin(AcceptSocketAsync(), callback, state);
+            TaskToAsyncResult.Begin(AcceptSocketAsync(), callback, state);
 
         public Socket EndAcceptSocket(IAsyncResult asyncResult) =>
             EndAcceptCore<Socket>(asyncResult);
 
         public IAsyncResult BeginAcceptTcpClient(AsyncCallback? callback, object? state) =>
-            TaskToApm.Begin(AcceptTcpClientAsync(), callback, state);
+            TaskToAsyncResult.Begin(AcceptTcpClientAsync(), callback, state);
 
         public TcpClient EndAcceptTcpClient(IAsyncResult asyncResult) =>
             EndAcceptCore<TcpClient>(asyncResult);
@@ -283,7 +283,7 @@ namespace System.Net.Sockets
         {
             try
             {
-                return TaskToApm.End<TResult>(asyncResult);
+                return TaskToAsyncResult.End<TResult>(asyncResult);
             }
             catch (SocketException) when (!_active)
             {
index ad1851d..a1367f4 100644 (file)
@@ -92,8 +92,6 @@
              Link="Common\System\Threading\Tasks\TaskTimeoutExtensions.cs" />
     <Compile Include="$(CommonTestPath)System\Buffers\NativeMemoryManager.cs"
              Link="Common\System\Buffers\NativeMemoryManager.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="Common\System\Threading\Tasks\TaskToApm.cs" />
     <Compile Include="$(CommonTestPath)System\Diagnostics\Tracing\TestEventListener.cs"
              Link="Common\System\Diagnostics\Tracing\TestEventListener.cs" />
     <Compile Include="$(CommonPath)System\Net\Logging\NetEventSource.Common.cs"
index 2a8355c..ff1621f 100644 (file)
     <Compile Include="$(CommonPath)System\Threading\OpenExistingResult.cs">
       <Link>Common\System\Threading\OpenExistingResult.cs</Link>
     </Compile>
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs">
-      <Link>Common\System\Threading\Tasks\TaskToApm.cs</Link>
+    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToAsyncResult.cs">
+      <Link>Common\System\Threading\Tasks\TaskToAsyncResult.cs</Link>
     </Compile>
   </ItemGroup>
   <ItemGroup Condition="'$(IsMobileLike)' != 'true' and '$(FeatureNativeAot)' != 'true'">
index aabdf3c..40abcbd 100644 (file)
@@ -725,10 +725,10 @@ namespace System.IO
         }
 
         public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) =>
-            TaskToApm.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), callback, state);
+            TaskToAsyncResult.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), callback, state);
 
         public override int EndRead(IAsyncResult asyncResult) =>
-            TaskToApm.End<int>(asyncResult);
+            TaskToAsyncResult.End<int>(asyncResult);
 
         public override int ReadByte()
         {
@@ -1138,10 +1138,10 @@ namespace System.IO
         }
 
         public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) =>
-            TaskToApm.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), callback, state);
+            TaskToAsyncResult.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), callback, state);
 
         public override void EndWrite(IAsyncResult asyncResult) =>
-            TaskToApm.End(asyncResult);
+            TaskToAsyncResult.End(asyncResult);
 
         public override void WriteByte(byte value)
         {
index 9e8f37f..a221e80 100644 (file)
@@ -456,10 +456,10 @@ namespace System.IO.Strategies
         }
 
         public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
-            => TaskToApm.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), callback, state);
+            => TaskToAsyncResult.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), callback, state);
 
         public override int EndRead(IAsyncResult asyncResult)
-            => TaskToApm.End<int>(asyncResult);
+            => TaskToAsyncResult.End<int>(asyncResult);
 
         public override void Write(byte[] buffer, int offset, int count)
         {
@@ -739,10 +739,10 @@ namespace System.IO.Strategies
         }
 
         public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
-            => TaskToApm.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), callback, state);
+            => TaskToAsyncResult.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), callback, state);
 
         public override void EndWrite(IAsyncResult asyncResult)
-            => TaskToApm.End(asyncResult);
+            => TaskToAsyncResult.End(asyncResult);
 
         public override void SetLength(long value)
         {
index 83746a5..febe3d1 100644 (file)
@@ -246,10 +246,10 @@ namespace System.IO.Strategies
         }
 
         public sealed override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) =>
-            TaskToApm.Begin(WriteAsync(buffer, offset, count), callback, state);
+            TaskToAsyncResult.Begin(WriteAsync(buffer, offset, count), callback, state);
 
         public sealed override void EndWrite(IAsyncResult asyncResult) =>
-            TaskToApm.End(asyncResult);
+            TaskToAsyncResult.End(asyncResult);
 
         public sealed override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) =>
             WriteAsync(new ReadOnlyMemory<byte>(buffer, offset, count), cancellationToken).AsTask();
@@ -261,10 +261,10 @@ namespace System.IO.Strategies
         }
 
         public sealed override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) =>
-            TaskToApm.Begin(ReadAsync(buffer, offset, count), callback, state);
+            TaskToAsyncResult.Begin(ReadAsync(buffer, offset, count), callback, state);
 
         public sealed override int EndRead(IAsyncResult asyncResult) =>
-            TaskToApm.End<int>(asyncResult);
+            TaskToAsyncResult.End<int>(asyncResult);
 
         public sealed override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) =>
             ReadAsync(new Memory<byte>(buffer, offset, count), cancellationToken).AsTask();
index f3b723b..8c1c9bb 100644 (file)
@@ -1041,16 +1041,16 @@ namespace System.IO
                     Task.CompletedTask;
 
             public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) =>
-                TaskToApm.Begin(Task<int>.s_defaultResultTask, callback, state);
+                TaskToAsyncResult.Begin(Task<int>.s_defaultResultTask, callback, state);
 
             public override int EndRead(IAsyncResult asyncResult) =>
-                TaskToApm.End<int>(asyncResult);
+                TaskToAsyncResult.End<int>(asyncResult);
 
             public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) =>
-                TaskToApm.Begin(Task.CompletedTask, callback, state);
+                TaskToAsyncResult.Begin(Task.CompletedTask, callback, state);
 
             public override void EndWrite(IAsyncResult asyncResult) =>
-                TaskToApm.End(asyncResult);
+                TaskToAsyncResult.End(asyncResult);
 
             public override int Read(byte[] buffer, int offset, int count) => 0;
 
index 65be587..198e999 100644 (file)
@@ -83,10 +83,10 @@ namespace System.Text
         }
 
         public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
-            => TaskToApm.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), callback, state);
+            => TaskToAsyncResult.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), callback, state);
 
         public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
-            => TaskToApm.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), callback, state);
+            => TaskToAsyncResult.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), callback, state);
 
         protected override void Dispose(bool disposing)
         {
@@ -162,10 +162,10 @@ namespace System.Text
         }
 
         public override int EndRead(IAsyncResult asyncResult)
-            => TaskToApm.End<int>(asyncResult);
+            => TaskToAsyncResult.End<int>(asyncResult);
 
         public override void EndWrite(IAsyncResult asyncResult)
-            => TaskToApm.End(asyncResult);
+            => TaskToAsyncResult.End(asyncResult);
 
 #pragma warning disable CS3016 // Arrays as attribute arguments is not CLS-compliant
 #pragma warning disable CS8774 // Member must have a non-null value when exiting.
index 8388419..2de2139 100644 (file)
@@ -4,8 +4,6 @@
 // Changes to this file must follow the https://aka.ms/api-review process.
 // ------------------------------------------------------------------------------
 
-using System.Text;
-
 namespace Microsoft.Win32.SafeHandles
 {
     public abstract partial class CriticalHandleMinusOneIsInvalid : System.Runtime.InteropServices.CriticalHandle
@@ -14950,6 +14948,14 @@ namespace System.Threading.Tasks
         public new System.Threading.Tasks.Task<TResult> WaitAsync(System.TimeSpan timeout) { throw null; }
         public new System.Threading.Tasks.Task<TResult> WaitAsync(System.TimeSpan timeout, System.Threading.CancellationToken cancellationToken) { throw null; }
     }
+    public static partial class TaskToAsyncResult
+    {
+        public static System.IAsyncResult Begin(System.Threading.Tasks.Task task, System.AsyncCallback? callback, object? state) { throw null; }
+        public static void End(System.IAsyncResult asyncResult) { throw null; }
+        public static TResult End<TResult>(System.IAsyncResult asyncResult) { throw null; }
+        public static System.Threading.Tasks.Task Unwrap(System.IAsyncResult asyncResult) { throw null; }
+        public static System.Threading.Tasks.Task<TResult> Unwrap<TResult>(System.IAsyncResult asyncResult) { throw null; }
+    }
     public partial class UnobservedTaskExceptionEventArgs : System.EventArgs
     {
         public UnobservedTaskExceptionEventArgs(System.AggregateException exception) { }
index af007a2..197dba5 100644 (file)
@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <DefineConstants>$(DefineConstants);INTERNAL_ASYMMETRIC_IMPLEMENTATIONS</DefineConstants>
              Link="Common\System\Security\Cryptography\Utf8DataEncoding.cs" />
     <Compile Include="$(CommonPath)System\Text\ValueStringBuilder.cs"
              Link="Common\System\Text\ValueStringBuilder.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="Common\System\Threading\Tasks\TaskToApm.cs" />
     <Compile Include="Microsoft\Win32\SafeHandles\SafePasswordHandle.cs" />
     <Compile Include="System\Security\Cryptography\Aes.cs" />
     <Compile Include="System\Security\Cryptography\AesAEAD.cs" />
index c1cc9a9..f85b396 100644 (file)
@@ -249,10 +249,10 @@ namespace System.Security.Cryptography
         }
 
         public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) =>
-            TaskToApm.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), callback, state);
+            TaskToAsyncResult.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), callback, state);
 
         public override int EndRead(IAsyncResult asyncResult) =>
-            TaskToApm.End<int>(asyncResult);
+            TaskToAsyncResult.End<int>(asyncResult);
 
         public override int ReadByte()
         {
@@ -488,10 +488,10 @@ namespace System.Security.Cryptography
         }
 
         public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) =>
-            TaskToApm.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), callback, state);
+            TaskToAsyncResult.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), callback, state);
 
         public override void EndWrite(IAsyncResult asyncResult) =>
-            TaskToApm.End(asyncResult);
+            TaskToAsyncResult.End(asyncResult);
 
         public override void Write(byte[] buffer, int offset, int count)
         {
index bfbb590..86e3d51 100644 (file)
              Link="CommonTest\System\Security\Cryptography\CryptoUtils.cs" />
     <Compile Include="$(CommonTestPath)System\Security\Cryptography\PlatformSupport.cs"
              Link="CommonTest\System\Security\Cryptography\PlatformSupport.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="Common\System\Threading\Tasks\TaskToApm.cs" />
   </ItemGroup>
   <ItemGroup>
     <Compile Include="AesCcmTests.cs" />
index 305e53a..a0c5f7f 100644 (file)
@@ -86,7 +86,6 @@
     <Compile Include="UnicodeEncoding\UnicodeEncoding.cs" />
     <Compile Include="Decoder\Decoder.cs" />
     <Compile Include="Encoder\Encoder.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs" Link="Common\System\Threading\Tasks\TaskToApm.cs" />
     <Compile Include="$(CommonTestPath)System\IO\ConnectedStreams.cs" Link="Common\System\IO\ConnectedStreams.cs" />
     <Compile Include="$(CommonPath)System\Net\ArrayBuffer.cs" Link="ProductionCode\Common\System\Net\ArrayBuffer.cs" />
     <Compile Include="$(CommonPath)System\Net\MultiArrayBuffer.cs" Link="ProductionCode\Common\System\Net\MultiArrayBuffer.cs" />
@@ -99,4 +98,4 @@
     <ProjectReference Include="$(CommonTestPath)StreamConformanceTests\StreamConformanceTests.csproj" />
     <ProjectReference Include="$(LibrariesProjectRoot)System.IO.Pipelines\src\System.IO.Pipelines.csproj" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
index 8bebfb2..468c31b 100644 (file)
@@ -16,6 +16,7 @@
     <Compile Include="CancellationTokenTests.cs" />
     <Compile Include="MethodCoverage.cs" />
     <Compile Include="CESchedulerPairTests.cs" />
+    <Compile Include="TaskToAsyncResultTests.cs" />
     <!-- Task -->
     <Compile Include="Task\AsyncEnumerableToBlockingEnumerableTests.cs" />
     <Compile Include="Task\ExecutionContextFlowTest.cs" />
diff --git a/src/libraries/System.Threading.Tasks/tests/TaskToAsyncResultTests.cs b/src/libraries/System.Threading.Tasks/tests/TaskToAsyncResultTests.cs
new file mode 100644 (file)
index 0000000..57d703f
--- /dev/null
@@ -0,0 +1,164 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Xunit;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace System.Threading.Tasks.Tests
+{
+    public class TaskToAsyncResultTests
+    {
+        [Fact]
+        public void InvalidArguments_ThrowExceptions()
+        {
+            AssertExtensions.Throws<ArgumentNullException>("task", () => TaskToAsyncResult.Begin(null, null, null));
+            AssertExtensions.Throws<ArgumentNullException>("task", () => TaskToAsyncResult.Begin(null, iar => { }, "test"));
+
+            AssertExtensions.Throws<ArgumentNullException>("asyncResult", () => TaskToAsyncResult.End(null));
+            AssertExtensions.Throws<ArgumentNullException>("asyncResult", () => TaskToAsyncResult.End<int>(null));
+
+            AssertExtensions.Throws<ArgumentException>("asyncResult", () => TaskToAsyncResult.End(new NonTaskIAsyncResult()));
+            AssertExtensions.Throws<ArgumentException>("asyncResult", () => TaskToAsyncResult.End<int>(new NonTaskIAsyncResult()));
+            AssertExtensions.Throws<ArgumentException>("asyncResult", () => TaskToAsyncResult.End<int>(Task.FromResult((long)42)));
+
+            AssertExtensions.Throws<ArgumentException>("asyncResult", () => TaskToAsyncResult.Unwrap(new NonTaskIAsyncResult()));
+            AssertExtensions.Throws<ArgumentException>("asyncResult", () => TaskToAsyncResult.Unwrap<int>(new NonTaskIAsyncResult()));
+            AssertExtensions.Throws<ArgumentException>("asyncResult", () => TaskToAsyncResult.Unwrap<int>(Task.FromResult((long)42)));
+        }
+
+        [Fact]
+        public async Task BeginFromTask_UnwrapTask_EndFromTask_Roundtrips()
+        {
+            var tcs = new TaskCompletionSource<int>();
+            object state = new object();
+
+            IAsyncResult ar = TaskToAsyncResult.Begin(tcs.Task, null, state);
+            Assert.NotNull(ar);
+            Assert.Same(state, ar.AsyncState);
+            Assert.NotNull(ar.AsyncWaitHandle);
+            Assert.False(ar.CompletedSynchronously);
+            Assert.False(ar.IsCompleted);
+
+            Assert.Same(tcs.Task, TaskToAsyncResult.Unwrap(ar));
+            Assert.Same(tcs.Task, TaskToAsyncResult.Unwrap<int>(ar));
+
+            tcs.SetResult(42);
+            await tcs.Task;
+
+            Assert.True(ar.IsCompleted);
+            Assert.False(ar.CompletedSynchronously);
+            Assert.True(ar.AsyncWaitHandle.WaitOne(0));
+
+            TaskToAsyncResult.End(ar);
+            Assert.Equal(42, TaskToAsyncResult.End<int>(ar));
+        }
+
+        [Fact]
+        public void BeginFromTask_CompletedSynchronously_CallbackInvokedSynchronously()
+        {
+            Task<int> t = Task.FromResult(42);
+            object state = new object();
+
+            int id = Environment.CurrentManagedThreadId;
+
+            IAsyncResult arCallback = null;
+            IAsyncResult ar = TaskToAsyncResult.Begin(t, iar =>
+            {
+                arCallback = iar;
+
+                Assert.True(iar.CompletedSynchronously);
+                Assert.True(iar.IsCompleted);
+                Assert.Same(state, iar.AsyncState);
+
+                Assert.Equal(id, Environment.CurrentManagedThreadId);
+
+                Assert.Equal(42, TaskToAsyncResult.End<int>(iar));
+            }, state);
+
+            Assert.Same(ar, arCallback);
+            Assert.True(ar.CompletedSynchronously);
+            Assert.True(ar.IsCompleted);
+            Assert.Same(state, ar.AsyncState);
+        }
+
+        [Fact]
+        public async void BeginFromTask_CompletedAsynchronously_CallbackInvokedAsynchronously()
+        {
+            var tcs = new TaskCompletionSource();
+            var invoked = new TaskCompletionSource();
+
+            var tl = new ThreadLocal<int>();
+            tl.Value = 42;
+            IAsyncResult ar = TaskToAsyncResult.Begin(tcs.Task, iar =>
+            {
+                Assert.NotEqual(42, tl.Value);
+                Assert.False(iar.CompletedSynchronously);
+                Assert.True(iar.IsCompleted);
+                Assert.Null(iar.AsyncState);
+                invoked.SetResult();
+            }, null);
+            tl.Value = 0;
+
+            Assert.False(invoked.Task.IsCompleted);
+            Assert.False(ar.CompletedSynchronously);
+            Assert.False(ar.IsCompleted);
+            Assert.Null(ar.AsyncState);
+            Assert.NotNull(ar.AsyncWaitHandle);
+            Assert.False(ar.AsyncWaitHandle.WaitOne(0));
+
+            tcs.SetResult();
+            await invoked.Task;
+
+            Assert.False(ar.CompletedSynchronously);
+            Assert.True(ar.IsCompleted);
+            Assert.Null(ar.AsyncState);
+            Assert.NotNull(ar.AsyncWaitHandle);
+            Assert.True(ar.AsyncWaitHandle.WaitOne(0));
+        }
+
+        [Fact]
+        public void EndFromTask_PropagatesExceptions()
+        {
+            IAsyncResult ar = TaskToAsyncResult.Begin(Task.FromException(new FormatException()), null, null);
+            Assert.Throws<FormatException>(() => TaskToAsyncResult.End(ar));
+
+            ar = TaskToAsyncResult.Begin(Task.FromException<int>(new FormatException()), null, null);
+            Assert.Throws<FormatException>(() => TaskToAsyncResult.End<int>(ar));
+        }
+
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))]
+        public async Task WithFromAsync_IAsyncResult_Roundtrips()
+        {
+            var tcs = new TaskCompletionSource();
+            var invoked = new TaskCompletionSource();
+            _ = Task.Factory.FromAsync(TaskToAsyncResult.Begin(tcs.Task, null, null), iar =>
+            {
+                invoked.SetResult();
+            });
+            tcs.SetResult();
+            await invoked.Task;
+        }
+
+        [Fact]
+        public async Task WithFromAsync_Delegate_Roundtrips()
+        {
+            var tcs = new TaskCompletionSource();
+            var invoked = new TaskCompletionSource();
+            _ = Task.Factory.FromAsync(
+                (callback, state) => TaskToAsyncResult.Begin(tcs.Task, callback, state),
+                iar => invoked.SetResult(),
+                new object());
+            tcs.SetResult();
+            await invoked.Task;
+        }
+    }
+
+    internal sealed class NonTaskIAsyncResult : IAsyncResult
+    {
+        public object? AsyncState { get; set; }
+        public WaitHandle AsyncWaitHandle { get; set; }
+        public bool CompletedSynchronously { get; set; }
+        public bool IsCompleted { get; set; }
+    }
+}
index 2049b6e..33ed30d 100644 (file)
@@ -70,7 +70,7 @@ public class Tests {
                        var d = new UnhandledExceptionEventHandler (helper.OnUnhandled);
                        AppDomain.CurrentDomain.UnhandledException += d;
 
-                       // this is TaskToApm.Begin (..., callback) where the callback is helper.WhenCompleted
+                       // this is TaskToAsyncResult.Begin (..., callback) where the callback is helper.WhenCompleted
                        Task.Delay (100).GetAwaiter().OnCompleted (helper.WhenCompleted);
 
                        var wasSet = helper.WaitForExn (10000); // wait upto 10 seconds for the task to throw