private static void GetDevicesFromSocket(IPEndPoint multicastIPEndpoint, IProgress <Device> deviceFoundCallback, Socket ssdpSocket, Dictionary <string, Device> devices)
        {
            ssdpSocket.SendTo(
                Encoding.ASCII.GetBytes(string.Format(DeviceLocator._ssdpMessage, multicastIPEndpoint.Address)),
                SocketFlags.None,
                multicastIPEndpoint
                );

            var stopWatch = Stopwatch.StartNew();

            try
            {
                while (stopWatch.Elapsed < TimeSpan.FromSeconds(1))
                {
                    try // Catch socket read exception
                    {
                        int available = ssdpSocket.Available;

                        if (available > 0)
                        {
                            var buffer            = new byte[available];
                            int numberOfBytesRead = ssdpSocket.Receive(buffer, SocketFlags.None);

                            if (numberOfBytesRead > 0)
                            {
                                string response = Encoding.UTF8.GetString(buffer.Take(numberOfBytesRead).ToArray());
                                Device device   = DeviceLocator.GetDeviceInformationFromSsdpMessage(response);

                                if (!devices.ContainsKey(device.Hostname))
                                {
                                    devices.Add(device.Hostname, device);
                                    deviceFoundCallback?.Report(device);
                                }
                            }
                        }
                    }
                    catch (SocketException)
                    {
                        // Ignore SocketException and continue polling
                    }

                    Thread.Sleep(TimeSpan.FromMilliseconds(10));
                }
            }
            finally
            {
                stopWatch.Stop();
            }
        }
        private static List <Task <List <Device> > > CreateDiscoverTasks(NetworkInterface netInterface, int retryCount)
        {
            var devices = new ConcurrentDictionary <string, Device>();
            var tasks   = new List <Task <List <Device> > >();

            if (netInterface.NetworkInterfaceType != NetworkInterfaceType.Wireless80211 &&
                netInterface.NetworkInterfaceType != NetworkInterfaceType.Ethernet)
            {
                return(tasks);
            }

            foreach (UnicastIPAddressInformation ip in netInterface.GetIPProperties().UnicastAddresses)
            {
                if (ip.Address.AddressFamily != AddressFamily.InterNetwork)
                {
                    continue;
                }

                for (var count = 0; count < retryCount; count++)
                {
                    Task <List <Device> > t = Task.Run(
                        async() =>
                    {
                        var stopWatch = new Stopwatch();
                        try
                        {
                            using (var ssdpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
                            {
                                Blocking = false,
                                Ttl = 1,
                                UseOnlyOverlappedIO = true,
                                MulticastLoopback = false
                            })
                            {
                                ssdpSocket.Bind(new IPEndPoint(ip.Address, 0));
                                ssdpSocket.SetSocketOption(
                                    SocketOptionLevel.IP,
                                    SocketOptionName.AddMembership,
                                    new MulticastOption(DeviceLocator._multicastEndPoint.Address));

                                ssdpSocket.SendTo(
                                    DeviceLocator._ssdpDiagram,
                                    SocketFlags.None,
                                    DeviceLocator._multicastEndPoint);

                                stopWatch.Start();
                                while (stopWatch.Elapsed < TimeSpan.FromSeconds(1))
                                {
                                    try
                                    {
                                        int available = ssdpSocket.Available;

                                        if (available > 0)
                                        {
                                            var buffer = new byte[available];
                                            int i      = ssdpSocket.Receive(buffer, SocketFlags.None);

                                            if (i > 0)
                                            {
                                                string response = Encoding.UTF8.GetString(buffer.Take(i).ToArray());
                                                Device device   = DeviceLocator.GetDeviceInformationFromSsdpMessage(response);

                                                //add only if no device already matching
                                                if (devices.TryAdd(device.Hostname, device))
                                                {
                                                    DeviceLocator.OnDeviceFound?.Invoke(null, new DeviceFoundEventArgs(device));
                                                }
                                            }
                                        }
                                    }
                                    catch (SocketException)
                                    {
                                        // Continue polling
                                    }

                                    await Task.Delay(TimeSpan.FromMilliseconds(10));
                                }

                                stopWatch.Stop();
                            }
                        }
                        catch (SocketException)
                        {
                            return(devices.Values.ToList());
                        }
                        finally
                        {
                            stopWatch.Stop();
                        }

                        return(devices.Values.ToList());
                    });

                    tasks.Add(t);
                }
            }

            return(tasks);
        }