Remove FromAsync usage from System.Net.NetworkInformation (#35710)
authorStephen Toub <stoub@microsoft.com>
Sat, 2 May 2020 19:24:59 +0000 (15:24 -0400)
committerGitHub <noreply@github.com>
Sat, 2 May 2020 19:24:59 +0000 (15:24 -0400)
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/tests/FunctionalTests/IPGlobalPropertiesTest.cs

index 3b8c89f32df7c7e8ed24fea95d8d8b2a2f38787a..1b1b6bf5a74e1d6612dc458d9e67c51c5e3c58d0 100644 (file)
@@ -52,6 +52,8 @@
              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="'$(TargetsWindows)' == 'true'">
     <!-- Logging -->
              Link="Common\Interop\Unix\System.Native\Interop.MapTcpState.cs" />
     <Compile Include="$(CommonPath)Interop\Unix\Interop.Errors.cs"
              Link="Common\Interop\CoreLib\Unix\Interop.Errors.cs" />
-    <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs"
-             Link="Common\System\Threading\Tasks\TaskToApm.cs" />
     <Compile Include="$(CommonPath)System\IO\RowConfigReader.cs"
              Link="Common\System\IO\RowConfigReader.cs" />
   </ItemGroup>
index f98dcaed80ee930da7be3304ee7fbe00442c1807..315915b5ed0c3ba677782d9fd48de5aec4f665f2 100644 (file)
@@ -2,17 +2,14 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
-using Microsoft.Win32.SafeHandles;
-
 using System.Collections.Generic;
 using System.Net.Sockets;
 using System.Runtime.InteropServices;
-using System.Threading;
 using System.Threading.Tasks;
 
 namespace System.Net.NetworkInformation
 {
-    internal class SystemIPGlobalProperties : IPGlobalProperties
+    internal sealed class SystemIPGlobalProperties : IPGlobalProperties
     {
         internal SystemIPGlobalProperties()
         {
@@ -371,96 +368,39 @@ namespace System.Net.NetworkInformation
             return new SystemIcmpV6Statistics();
         }
 
-        public override IAsyncResult BeginGetUnicastAddresses(AsyncCallback? callback, object? state)
-        {
-            ContextAwareResult asyncResult = new ContextAwareResult(false, false, this, state, callback);
-            asyncResult.StartPostingAsyncOp(false);
-            if (TeredoHelper.UnsafeNotifyStableUnicastIpAddressTable(StableUnicastAddressTableCallback, asyncResult))
-            {
-                asyncResult.InvokeCallback();
-            }
-
-            asyncResult.FinishPostingAsyncOp();
-
-            return asyncResult;
-        }
-
-        public override UnicastIPAddressInformationCollection EndGetUnicastAddresses(IAsyncResult asyncResult)
-        {
-            if (asyncResult == null)
-            {
-                throw new ArgumentNullException(nameof(asyncResult));
-            }
-
-            ContextAwareResult? result = asyncResult as ContextAwareResult;
-            if (result == null || result.AsyncObject == null || result.AsyncObject.GetType() != typeof(SystemIPGlobalProperties))
-            {
-                throw new ArgumentException(SR.net_io_invalidasyncresult);
-            }
-
-            if (result.EndCalled)
-            {
-                throw new InvalidOperationException(SR.Format(SR.net_io_invalidendcall, "EndGetStableUnicastAddresses"));
-            }
-
-            result.InternalWaitForCompletion();
-
-            result.EndCalled = true;
-            return GetUnicastAddressTable();
-        }
-
-        public override UnicastIPAddressInformationCollection GetUnicastAddresses()
-        {
-            // Wait for the Address Table to stabilize
-            using (ManualResetEvent stable = new ManualResetEvent(false))
-            {
-                if (!TeredoHelper.UnsafeNotifyStableUnicastIpAddressTable(StableUnicastAddressTableCallback, stable))
-                {
-                    stable.WaitOne();
-                }
-            }
+        public override IAsyncResult BeginGetUnicastAddresses(AsyncCallback? callback, object? state) =>
+            TaskToApm.Begin(GetUnicastAddressesAsync(), callback, state);
 
-            return GetUnicastAddressTable();
-        }
+        public override UnicastIPAddressInformationCollection EndGetUnicastAddresses(IAsyncResult asyncResult) =>
+            TaskToApm.End<UnicastIPAddressInformationCollection>(asyncResult);
 
-        public override Task<UnicastIPAddressInformationCollection> GetUnicastAddressesAsync()
-        {
-            return Task<UnicastIPAddressInformationCollection>.Factory.FromAsync(BeginGetUnicastAddresses, EndGetUnicastAddresses, null);
-        }
+        public override UnicastIPAddressInformationCollection GetUnicastAddresses() =>
+            GetUnicastAddressesAsync().GetAwaiter().GetResult();
 
-        private static void StableUnicastAddressTableCallback(object param)
+        public override async Task<UnicastIPAddressInformationCollection> GetUnicastAddressesAsync()
         {
-            EventWaitHandle? handle = param as EventWaitHandle;
-            if (handle != null)
-            {
-                handle.Set();
-            }
-            else
+            // Wait for the address table to stabilize.
+            var tcs = new TaskCompletionSource<bool>(TaskContinuationOptions.RunContinuationsAsynchronously);
+            if (!TeredoHelper.UnsafeNotifyStableUnicastIpAddressTable(s => ((TaskCompletionSource<bool>)s).TrySetResult(true), tcs))
             {
-                LazyAsyncResult asyncResult = (LazyAsyncResult)param;
-                asyncResult.InvokeCallback();
+                await tcs.Task.ConfigureAwait(false);
             }
-        }
 
-        private static UnicastIPAddressInformationCollection GetUnicastAddressTable()
-        {
-            UnicastIPAddressInformationCollection rval = new UnicastIPAddressInformationCollection();
+            // Get the address table.
+            var addresses = new UnicastIPAddressInformationCollection();
 
-            NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces();
-            for (int i = 0; i < interfaces.Length; ++i)
+            foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
             {
-                UnicastIPAddressInformationCollection addresses = interfaces[i].GetIPProperties().UnicastAddresses;
-
-                foreach (UnicastIPAddressInformation address in addresses)
+                foreach (UnicastIPAddressInformation address in ni.GetIPProperties().UnicastAddresses)
                 {
-                    if (!rval.Contains(address))
+                    if (!addresses.Contains(address))
                     {
-                        rval.InternalAdd(address);
+                        addresses.InternalAdd(address);
                     }
                 }
             }
 
-            return rval;
+            return addresses;
         }
     }
 }
index 236c9dcb7f361fb19a5ee0f5aa4014c2f69bcc55..b5134e10728f61d67f408c4b66eadae12f1973c3 100644 (file)
@@ -116,5 +116,14 @@ namespace System.Net.NetworkInformation.Tests
                 Assert.NotEqual(TcpState.Listen, ti.State);
             }
         }
+
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsSubsystemForLinux))] // [ActiveIssue("https://github.com/dotnet/runtime/issues/18258")]
+        public async Task GetUnicastAddresses_NotEmpty()
+        {
+            IPGlobalProperties props = IPGlobalProperties.GetIPGlobalProperties();
+            Assert.NotEmpty(props.GetUnicastAddresses());
+            Assert.NotEmpty(await props.GetUnicastAddressesAsync());
+            Assert.NotEmpty(await Task.Factory.FromAsync(props.BeginGetUnicastAddresses, props.EndGetUnicastAddresses, null));
+        }
     }
 }