public AsyncTileRequest CreateRequest(Uri uri, TileInfo tileInfo, NetworkPriority networkPriority, AsyncTileRequestCompletedHandler callback) { AsyncTileRequest tempTileRequest = new AsyncTileRequest(uri, tileInfo, callback) { NetworkPriority = networkPriority }; lock (this.pendingRequests) { this.pendingRequests.Add(tempTileRequest); } this.thereMayBeWorkToDo.Set(); return(tempTileRequest); }
private void DownloadThreadStart() { while (true) { WaitHandle[] waitHandleArray = new WaitHandle[] { this.thereMayBeWorkToDo }; WaitHandle.WaitAll(waitHandleArray); AsyncTileRequest tempTileREQUEST = null; lock (this.executingRequests) { lock (this.pendingRequests) { (from pendingRequest in this.pendingRequests where pendingRequest.IsAborted select pendingRequest).ToList <AsyncTileRequest>().ForEach((AsyncTileRequest tr) => this.pendingRequests.Remove(tr)); foreach (AsyncTileRequest pendingRequest in this.pendingRequests) { pendingRequest.NetworkPrioritySnapshot = pendingRequest.NetworkPriority; } this.pendingRequests.Sort((AsyncTileRequest left, AsyncTileRequest right) => Comparer <int> .Default.Compare((int)left.NetworkPrioritySnapshot, (int)right.NetworkPrioritySnapshot)); if (this.executingRequests.Count >= AsyncTileRequestQueue.MaxSimultaneousRequests || this.pendingRequests.Count <= 0) { this.thereMayBeWorkToDo.Reset(); } else { tempTileREQUEST = this.pendingRequests[this.pendingRequests.Count - 1]; this.pendingRequests.RemoveAt(this.pendingRequests.Count - 1); } } if (tempTileREQUEST != null) { WebClient webClient = new WebClient() { CachePolicy = new RequestCachePolicy(RequestCacheLevel.CacheIfAvailable), Proxy = WebProxy, Credentials = Credentials }; webClient.DownloadDataCompleted += new DownloadDataCompletedEventHandler(this.DownloadDataCompleted); this.executingRequests.Add(tempTileREQUEST, webClient); webClient.DownloadDataAsync(tempTileREQUEST.Uri, null); } } } }
private void DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e) { AsyncTileRequest key = null; lock (this.executingRequests) { KeyValuePair <AsyncTileRequest, WebClient> keyValuePair = this.executingRequests.First <KeyValuePair <AsyncTileRequest, WebClient> >((KeyValuePair <AsyncTileRequest, WebClient> item) => item.Value == sender); key = keyValuePair.Key; this.executingRequests.Remove(key); this.thereMayBeWorkToDo.Set(); } byte[] requestedTileInBytes = null; Exception error = e.Error; if (error == null) { try { if ((int)e.Result.Length <= 0) { error = new Exception("empty result"); } else { requestedTileInBytes = e.Result; } } catch (Exception exception) { error = exception; requestedTileInBytes = null; } } // Save the requested tile into cache. if (requestedTileInBytes != null && key.TileInfo != null && TileCache != null) { TileCache.Save(key.TileInfo, requestedTileInBytes); } key.Callback(requestedTileInBytes, error); ((WebClient)sender).Dispose(); }