public void GetAddresses(Region region, IpFilter filter, int maxResults, MasterIpCallback callback)
        {
            try
            {
                using (var client = new XWebClient())
                {
                    var text = client.DownloadString(this.url);
                    if (text == null)
                    {
                        callback(null, null, false);
                        return;
                    }

                    var lines     = text.Split('\n');
                    var endpoints = new List <Tuple <IPEndPoint, ServerInfo> >(lines.Length);
                    int i         = 0;
                    foreach (var line in lines)
                    {
                        if (string.IsNullOrWhiteSpace(line))
                        {
                            continue;
                        }
                        var parts = line.Split(':');
                        if (parts.Length != 2)
                        {
                            continue;
                        }

                        IPAddress addr;
                        int       port;
                        if (IPAddress.TryParse(parts[0], out addr) && int.TryParse(parts[1].TrimEnd(), out port))
                        {
                            endpoints.Add(new Tuple <IPEndPoint, ServerInfo>(new IPEndPoint(addr, port), null));
                            if (++i == maxResults)
                            {
                                break;
                            }
                        }
                    }
                    callback(new ReadOnlyCollection <Tuple <IPEndPoint, ServerInfo> >(endpoints), null, false);
                }
            }
            catch (Exception ex)
            {
                callback(null, ex, false);
            }
        }
        private void ProcessLoop()
        {
            using (var client = new XWebClient(5000))
            {
                while (true)
                {
                    var ip = this.queue.Take();
                    if (ip == null)
                    {
                        break;
                    }

                    bool err   = true;
                    var  ipInt = Ip4Utils.ToInt(ip);
                    try
                    {
                        var url    = string.Format(this.ServiceUrlFormat, ip);
                        var result = client.DownloadString(url);
                        if (result != null)
                        {
                            object           o;
                            Action <GeoInfo> callbacks;
                            lock (cache)
                                callbacks = cache.TryGetValue(ipInt, out o) ? o as Action <GeoInfo> : null;
                            var geoInfo = this.HandleResult(ipInt, result);
                            if (callbacks != null && geoInfo != null)
                            {
                                ThreadPool.QueueUserWorkItem(ctx => callbacks(geoInfo));
                            }
                            err = false;
                        }
                    }
                    catch
                    {
                        // ignore
                    }

                    if (err)
                    {
                        lock (this.cache)
                            this.cache.Remove(ipInt);
                    }
                }
            }
        }