/// <summary>
        /// Asynchronously requests wireless interfaces to scan (rescan) wireless LANs.
        /// </summary>
        /// <param name="timeout">Timeout duration</param>
        /// <param name="cancellationToken">Cancellation token</param>
        /// <returns>Interface IDs that successfully scanned</returns>
        public static async Task <IEnumerable <Guid> > ScanNetworksAsync(TimeSpan timeout, CancellationToken cancellationToken)
        {
            using (var client = new Base.WlanClient())
            {
                var interfaceInfoList = Base.GetInterfaceInfoList(client.Handle);
                var interfaceIds      = interfaceInfoList.Select(x => x.InterfaceGuid).ToArray();

                var tcs     = new TaskCompletionSource <bool>();
                var handler = new ScanHandler(tcs, interfaceIds);

                Action <IntPtr, IntPtr> callback = (data, context) =>
                {
                    var notificationData = Marshal.PtrToStructure <WLAN_NOTIFICATION_DATA>(data);
                    if (notificationData.NotificationSource != WLAN_NOTIFICATION_SOURCE_ACM)
                    {
                        return;
                    }

                    Debug.WriteLine("Callback: {0}", (WLAN_NOTIFICATION_ACM)notificationData.NotificationCode);

                    switch (notificationData.NotificationCode)
                    {
                    case (uint)WLAN_NOTIFICATION_ACM.wlan_notification_acm_scan_complete:
                        handler.SetSuccess(notificationData.InterfaceGuid);
                        break;

                    case (uint)WLAN_NOTIFICATION_ACM.wlan_notification_acm_scan_fail:
                        handler.SetFailure(notificationData.InterfaceGuid);
                        break;
                    }
                };

                Base.RegisterNotification(client.Handle, WLAN_NOTIFICATION_SOURCE_ACM, callback);

                foreach (var interfaceId in interfaceIds)
                {
                    var result = Base.Scan(client.Handle, interfaceId);
                    if (!result)
                    {
                        handler.SetFailure(interfaceId);
                    }
                }

                var scanTask = tcs.Task;
                await Task.WhenAny(scanTask, Task.Delay(timeout, cancellationToken));

                return(handler.Results);
            }
        }