System.Net.NetworkInformation.NetworkChange.AddressChangeListener.StartHelper C# (CSharp) Method

StartHelper() private static method

private static StartHelper ( NetworkAddressChangedEventHandler caller, bool captureContext, StartIPOptions startIPOptions ) : void
caller NetworkAddressChangedEventHandler
captureContext bool
startIPOptions StartIPOptions
return void
            private static void StartHelper(NetworkAddressChangedEventHandler caller, bool captureContext, StartIPOptions startIPOptions)
            {
                lock (s_callerArray)
                {
                    // Setup changedEvent and native overlapped struct.
                    if (s_ipv4Socket == null)
                    {
                        int blocking;

                        // Sockets will be initialized by the call to OSSupportsIP*.
                        if (Socket.OSSupportsIPv4)
                        {
                            blocking = -1;
                            s_ipv4Socket = SafeCloseSocketAndEvent.CreateWSASocketWithEvent(AddressFamily.InterNetwork, SocketType.Dgram, (ProtocolType)0, true, false);
                            Interop.Winsock.ioctlsocket(s_ipv4Socket, Interop.Winsock.IoctlSocketConstants.FIONBIO, ref blocking);
                            s_ipv4WaitHandle = s_ipv4Socket.GetEventHandle();
                        }

                        if (Socket.OSSupportsIPv6)
                        {
                            blocking = -1;
                            s_ipv6Socket = SafeCloseSocketAndEvent.CreateWSASocketWithEvent(AddressFamily.InterNetworkV6, SocketType.Dgram, (ProtocolType)0, true, false);
                            Interop.Winsock.ioctlsocket(s_ipv6Socket, Interop.Winsock.IoctlSocketConstants.FIONBIO, ref blocking);
                            s_ipv6WaitHandle = s_ipv6Socket.GetEventHandle();
                        }
                    }

                    if ((caller != null) && (!s_callerArray.ContainsKey(caller)))
                    {
                        s_callerArray.Add(caller, captureContext ? ExecutionContext.Capture() : null);
                    }

                    if (s_isListening || s_callerArray.Count == 0)
                    {
                        return;
                    }

                    if (!s_isPending)
                    {
                        int length;
                        SocketError errorCode;

                        if (Socket.OSSupportsIPv4 && (startIPOptions & StartIPOptions.StartIPv4) != 0)
                        {
                            s_registeredWait = ThreadPool.RegisterWaitForSingleObject(
                                s_ipv4WaitHandle,
                                new WaitOrTimerCallback(AddressChangedCallback),
                                StartIPOptions.StartIPv4,
                                -1,
                                true);

                            errorCode = Interop.Winsock.WSAIoctl_Blocking(
                                s_ipv4Socket.DangerousGetHandle(),
                                (int)IOControlCode.AddressListChange,
                                null, 0, null, 0,
                                out length,
                                SafeNativeOverlapped.Zero, IntPtr.Zero);

                            if (errorCode != SocketError.Success)
                            {
                                NetworkInformationException exception = new NetworkInformationException();
                                if (exception.ErrorCode != (uint)SocketError.WouldBlock)
                                {
                                    throw exception;
                                }
                            }

                            SafeWaitHandle s_ipv4SocketGetEventHandleSafeWaitHandle =
                                s_ipv4Socket.GetEventHandle().GetSafeWaitHandle();

                            errorCode = Interop.Winsock.WSAEventSelect(
                                s_ipv4Socket,
                                s_ipv4SocketGetEventHandleSafeWaitHandle,
                                Interop.Winsock.AsyncEventBits.FdAddressListChange);

                            if (errorCode != SocketError.Success)
                            {
                                throw new NetworkInformationException();
                            }
                        }

                        if (Socket.OSSupportsIPv6 && (startIPOptions & StartIPOptions.StartIPv6) != 0)
                        {
                            s_registeredWait = ThreadPool.RegisterWaitForSingleObject(
                                s_ipv6WaitHandle,
                                new WaitOrTimerCallback(AddressChangedCallback),
                                StartIPOptions.StartIPv6,
                                -1,
                                true);

                            errorCode = Interop.Winsock.WSAIoctl_Blocking(
                                s_ipv6Socket.DangerousGetHandle(),
                                (int)IOControlCode.AddressListChange,
                                null, 0, null, 0,
                                out length,
                                SafeNativeOverlapped.Zero, IntPtr.Zero);

                            if (errorCode != SocketError.Success)
                            {
                                NetworkInformationException exception = new NetworkInformationException();
                                if (exception.ErrorCode != (uint)SocketError.WouldBlock)
                                {
                                    throw exception;
                                }
                            }

                            SafeWaitHandle s_ipv6SocketGetEventHandleSafeWaitHandle =
                                s_ipv6Socket.GetEventHandle().GetSafeWaitHandle();

                            errorCode = Interop.Winsock.WSAEventSelect(
                                s_ipv6Socket,
                                s_ipv6SocketGetEventHandleSafeWaitHandle,
                                Interop.Winsock.AsyncEventBits.FdAddressListChange);

                            if (errorCode != SocketError.Success)
                            {
                                throw new NetworkInformationException();
                            }
                        }
                    }

                    s_isListening = true;
                    s_isPending = true;
                }
            }