public void Queue(StorageFolder folder, string fileName, string url, BitmapImage bmp) { PendingDownload pending; bool isFirstInQueue = false; lock (_lock) { PendingDownload existing = _list.FirstOrDefault(i => i.FileName.Equals(fileName) && i.Folder.IsEqual(folder)); if (existing != null) { if (bmp != null) { existing.BitmapImages.AddLast(bmp); } return; } pending = new PendingDownload(folder, fileName, url, bmp); _list.AddLast(pending); if (_list.Count == 1) { isFirstInQueue = true; } } //do it outside of lock so we don't keep locking for no reason if (isFirstInQueue) { sendDownloadedNeededEvent(pending); } }
private static async void download(PendingDownload pending) { try { if (!NetworkInterface.GetIsNetworkAvailable()) { foreach (BitmapImage bmp in pending.BitmapImages) { SetBitmapToOffline(bmp); } } else { HttpWebRequest req = WebRequest.CreateHttp(pending.Url); StorageFile file = await pending.Folder.CreateFileAsync(pending.FileName, CreationCollisionOption.ReplaceExisting); using (WebResponse resp = await req.GetResponseAsync()) { using (Stream storageStream = await file.OpenStreamForWriteAsync()) { await resp.GetResponseStream().CopyToAsync(storageStream); } } Uri uri = new Uri(file.Path); foreach (BitmapImage bmp in pending.BitmapImages) { bmp.UriSource = uri; } } } catch (WebException) { //set it to failed loading bitmap foreach (BitmapImage bmp in pending.BitmapImages) { SetBitmapToNotFound(bmp); } } catch { } //mark it finished, which might trigger loading the next pendingDownloads.MarkFinished(pending); }
public void MarkFinished(PendingDownload pending) { PendingDownload nextPending = null; lock (_lock) { _list.Remove(pending); nextPending = _list.FirstOrDefault(); } if (nextPending != null) { sendDownloadedNeededEvent(nextPending); } }
private static void pendingDownloads_DownloadNeeded(object sender, PendingDownload e) { download(e); }
private void sendDownloadedNeededEvent(PendingDownload pending) { DownloadNeeded(this, pending); }
public void OnMsg(AppStoreQuery msg) { if (netFail) { return; } var ack = new AppStoreAck(); try { switch (msg.Command) { case AppStoreQuery.GetPrimaryCmd: ack.StoreEP = this.PrimaryEP; break; case AppStoreQuery.ListCmd: ack.Packages = packageFolder.GetPackages(); break; case AppStoreQuery.RemoveCmd: packageFolder.Remove(msg.AppRef); break; case AppStoreQuery.SyncCmd: using (TimedLock.Lock(syncLock)) { this.forceSync = true; this.primaryPollTime = SysTime.Now; } break; case AppStoreQuery.DownloadCmd: ack.StoreEP = cluster.InstanceEP; MsgEP primaryEP; PendingDownload pending; using (TimedLock.Lock(syncLock)) { if (packageFolder.GetPackageInfo(msg.AppRef) != null) { break; // The package is ready for downloading } if (mode == AppStoreMode.Primary || this.PrimaryEP == null) { throw SessionException.Create(null, "Package [{0}] cannot be found.", msg.AppRef); } primaryEP = this.PrimaryEP; downloads.TryGetValue(msg.AppRef, out pending); } if (pending != null) { // A download is already pending for this package so wait // for it to complete. pending.Wait(); } else { // Try downloading the requested package from the primary // application store. string transitPath = null; pending = new PendingDownload(msg.AppRef); using (TimedLock.Lock(syncLock)) downloads.Add(msg.AppRef, pending); try { transitPath = packageFolder.BeginTransit(msg.AppRef); DownloadPackage(primaryEP, msg.AppRef, transitPath); packageFolder.EndTransit(transitPath, true); pending.Done(null); } catch (Exception e) { packageFolder.EndTransit(transitPath, false); pending.Done(e); throw; } finally { using (TimedLock.Lock(syncLock)) { try { downloads.Remove(msg.AppRef); } catch { // Ignore errors } } } } break; default: throw SessionException.Create("Unexpected AppStore command [{0}].", msg.Command); } } catch (Exception e) { ack.Exception = e.Message; SysLog.LogException(e); } router.ReplyTo(msg, ack); }