private static async Task RequestImagePathForCalendarStartRequestAsync(BingImageInfo info, RangeRequestInfo rangeInfo) { DateTime date; string path = null; Debug.WriteLine("Task for " + info.StartDate + " started"); if (!BingDataHelper.TryConvertStartdate(info.StartDate, out date)) { rangeInfo.Callback(date, false, null); return; } if (RequestImagePathCheckCache(info.StartDate, out path)) { rangeInfo.Callback(date, true, path); return; } await calendarRequestSemaphore.WaitAsync(); try { if (rangeInfo.IsCancelled) return; var fileName = info.StartDate + ".jpg"; var filePath = Path.Combine(Setting.GetCurrentSetting().TempPath.LocalPath, fileName); if (File.Exists(filePath)) File.Delete(filePath); // see if we can grab the 1080 source. if failed, try to get the 1366 source if (await RequestImagePathTryBingApiAsync(new Uri(BingBaseUri, info.Url), date, rangeInfo, filePath)) { if (rangeInfo.IsCancelled) return; if (RequestImagePathCheckCache(info.StartDate, out path)) { rangeInfo.Callback(date, true, path); return; } } else if (await RequestImagePathTryBingApiAsync(new Uri(BingBaseUri, info.UrlBase + "_1366x768.jpg"), date, rangeInfo, filePath)) { if (rangeInfo.IsCancelled) return; if (RequestImagePathCheckCache(info.StartDate, out path)) { rangeInfo.Callback(date, true, path); return; } } } catch (Exception e) { // any exception cause the thread to fail Debug.WriteLine(e.Message); } finally { rangeInfo.RemoveRequest(date); calendarRequestSemaphore.Release(); } if (!rangeInfo.IsCancelled) rangeInfo.Callback(date, false, null); }
private static async Task<bool> RequestImagePathTryBingApiAsync(Uri uri, DateTime date, RangeRequestInfo rangeInfo, string path) { var request = WebRequest.CreateHttp(uri); rangeInfo.SaveRequest(date, request); try { using (var response = await request.GetResponseAsync()) using (var stream = response.GetResponseStream()) { try { using (var image = Image.FromStream(stream, true, true)) { image.Save(path, ImageFormat.Jpeg); } return true; } catch (Exception) { } } } catch (WebException e) { // only consume case where response isn't canceled if (e.Status == WebExceptionStatus.RequestCanceled) throw e; } return false; }
public static async void StartRequestImagePathForCalendar(IEnumerable<DateTime> list, RangedQueryIndivisualResultCallback handler) { if (list == null) throw new ArgumentNullException("list"); if (handler == null) throw new ArgumentNullException("handler"); var currentRangeInfo = _currentRangeRequestInfo; if (currentRangeInfo != null) currentRangeInfo.StopTasks(); _currentRangeRequestInfo = currentRangeInfo = new RangeRequestInfo(handler); DateTime maxTime = DateTime.MinValue, minTime = DateTime.MaxValue; foreach (var item in list) { if (maxTime < item.Date) maxTime = item.Date; if (minTime > item.Date) minTime = item.Date; } var infos = await _readonlyStore.ReadImageInfosAsync(minTime, maxTime); if (infos != null) { var llist = new LinkedList<Task>(); for (int i = 0; i < infos.Length; i++) { var info = infos[i]; llist.AddLast(Task.Run(async () => await RequestImagePathForCalendarStartRequestAsync(info, currentRangeInfo))); if (llist.Count == 9) { // limit to 9 running at the same time await Task.WhenAny(llist); var walker = llist.First; while (walker != null) { if (walker.Value.IsCompleted) { var marked = walker; walker = walker.Next; llist.Remove(marked); } else walker = walker.Next; } } } llist.Clear(); // don't care about thread endstats; } }