Ejemplo n.º 1
0
 protected virtual void Dispose(bool disposing)
 {
     if (disposed)
     {
         return;
     }
     if (disposing)
     {
         Stop();
         int count = 50;
         while (PrefetchingBgWorker.IsBusy && count > 0)
         {
             Task.Delay(100).GetAwaiter().GetResult(); count--;
         }
         if (CanPrefetching is SemaphoreSlim && CanPrefetching.CurrentCount < 1)
         {
             CanPrefetching.Release();
         }
         PrefetchingBgWorker.Dispose();
         PrefetchedList.Clear();
         Items.Clear();
     }
     disposed = true;
 }
Ejemplo n.º 2
0
        private void PrefetchingTask_DoWork(object sender, DoWorkEventArgs e)
        {
            List <string> illusts       = new List <string>();
            List <string> originals     = new List <string>();
            List <string> avatars       = new List <string>();
            List <string> page_thumbs   = new List <string>();
            List <string> page_previews = new List <string>();
            List <string> needUpdate    = new List <string>();

            try
            {
                var args = e.Argument is PrefetchingOpts ? e.Argument as PrefetchingOpts : new PrefetchingOpts();
                if (!args.PrefetchingPreview)
                {
                    return;
                }

                LastStartTime = DateTime.Now;
                var pagesCount = CalcPagesThumbItems(Items);
                GetPreviewItems(illusts, avatars, page_thumbs, page_previews, originals);
                if (pagesCount != page_thumbs.Count + page_previews.Count)
                {
                    e.Cancel = true; return;
                }

                var total = illusts.Count + avatars.Count + page_thumbs.Count + page_previews.Count;
                if (total <= 0)
                {
                    e.Cancel = true; return;
                }
                var count = total;
                Percentage = count == 0 ? 100 : 0;
                Comments   = $"Calculating [ {count} / {total}, I:{illusts.Count} / A:{avatars.Count} / T:{page_thumbs.Count} / P:{page_previews.Count} ]";
                State      = TaskStatus.WaitingToRun;
                if (ReportProgressSlim is Action)
                {
                    ReportProgressSlim.Invoke(async: false);
                }
                else if (ReportProgress is Action <double, string, TaskStatus> )
                {
                    ReportProgress.Invoke(Percentage, Comments, State);
                }

                needUpdate.AddRange(args.ReverseOrder ? illusts.Reverse <string>() : illusts);
                needUpdate.AddRange(args.ReverseOrder ? avatars.Reverse <string>() : avatars);
                needUpdate.AddRange(args.ReverseOrder ? page_thumbs.Reverse <string>() : page_thumbs);
                needUpdate.AddRange(args.ReverseOrder ? page_previews.Reverse <string>() : page_previews);
                foreach (var url in needUpdate.Where(url => !PrefetchedList.ContainsKey(url) && File.Exists(url.GetImageCacheFile())))
                {
                    PrefetchedList.AddOrUpdate(url, true, (k, v) => true);
                    //if (!PrefetchedList.TryAdd(url, true)) PrefetchedList.TryUpdate(url, true, false);
                }
                needUpdate = needUpdate.Where(url => !PrefetchedList.ContainsKey(url) || !PrefetchedList[url]).ToList();
                count      = needUpdate.Count;
                Percentage = count == 0 ? 100 : (total - count) / (double)total * 100;
                if (count == 0)
                {
                    Comments = $"Done [ {count} / {total}, I:{illusts.Count} / A:{avatars.Count} / T:{page_thumbs.Count} / P:{page_previews.Count} ]";
                    State    = TaskStatus.RanToCompletion;
                }
                else
                {
                    Comments = $"Prefetching [ {count} / {total}, I:{illusts.Count} / A:{avatars.Count} / T:{page_thumbs.Count} / P:{page_previews.Count} ]";
                    State    = TaskStatus.Running;
                }
                if (ReportProgressSlim is Action)
                {
                    ReportProgressSlim.Invoke(async: false);
                }
                else if (ReportProgress is Action <double, string, TaskStatus> )
                {
                    ReportProgress.Invoke(Percentage, Comments, State);
                }
                this.DoEvents();
                if (count == 0)
                {
                    return;
                }

                var parallels = args.PrefetchingDownloadParallel;
                if (args.ParallelPrefetching)
                {
                    var opt = new ParallelOptions();
                    opt.MaxDegreeOfParallelism = parallels;
                    Parallel.ForEach(needUpdate, opt, (url, loopstate, urlIndex) =>
                    {
                        try
                        {
                            var file = url.GetImageCacheFile();
                            if (!string.IsNullOrEmpty(file))
                            {
                                if (File.Exists(file))
                                {
                                    PrefetchedList.AddOrUpdate(url, true, (k, v) => true);
                                    //if (!PrefetchedList.TryAdd(url, true)) PrefetchedList.TryUpdate(url, true, false);
                                    count = count - 1;
                                }
                                else
                                {
                                    var _downReport = DownloadProgressActions.ContainsKey(url) ? DownloadProgressActions[url] : null;
                                    file            = url.DownloadCacheFile(args.Overwrite, progressAction: _downReport, cancelToken: PrefetchingTaskCancelTokenSource).GetAwaiter().GetResult();
                                    if (!string.IsNullOrEmpty(file))
                                    {
                                        PrefetchedList.AddOrUpdate(url, true, (k, v) => true);
                                        //if (!PrefetchedList.TryAdd(url, true)) PrefetchedList.TryUpdate(url, true, false);
                                        count = count - 1;
                                    }
                                }
                            }
                            if (PrefetchingBgWorker.CancellationPending)
                            {
                                e.Cancel = true; State = TaskStatus.Canceled; loopstate.Stop();
                            }
                            Percentage = count == 0 ? 100 : (total - count) / (double)total * 100;
                            Comments   = $"Prefetching [ {count} / {total}, I:{illusts.Count} / A:{avatars.Count} / T:{page_thumbs.Count} / P:{page_previews.Count} ]";
                            State      = TaskStatus.Running;
                            if (ReportProgressSlim is Action)
                            {
                                ReportProgressSlim.Invoke(async: false);
                            }
                            else if (ReportProgress is Action <double, string, TaskStatus> )
                            {
                                ReportProgress.Invoke((double)this.Percentage, Comments, State);
                            }
                            this.DoEvents();
                        }
                        catch (Exception ex) { ex.ERROR("PREFETCHING"); }
                        finally { this.DoEvents(); Task.Delay(1).GetAwaiter().GetResult(); }
                    });
                }
                else
                {
                    SemaphoreSlim tasks = new SemaphoreSlim(parallels, parallels);
                    foreach (var url in needUpdate)
                    {
                        if (PrefetchingBgWorker.CancellationPending)
                        {
                            e.Cancel = true; break;
                        }
                        if (tasks.Wait(-1, PrefetchingTaskCancelTokenSource.Token))
                        {
                            new Action(async() =>
                            {
                                try
                                {
                                    var file = url.GetImageCacheFile();
                                    if (!string.IsNullOrEmpty(file))
                                    {
                                        if (File.Exists(file))
                                        {
                                            PrefetchedList.AddOrUpdate(url, true, (k, v) => true);
                                            //if (!PrefetchedList.TryAdd(url, true)) PrefetchedList.TryUpdate(url, true, false);
                                            count = count - 1;
                                        }
                                        else
                                        {
                                            var _downReport = DownloadProgressActions.ContainsKey(url) ? DownloadProgressActions[url] : null;
                                            file            = await url.DownloadCacheFile(args.Overwrite, progressAction: _downReport, cancelToken: PrefetchingTaskCancelTokenSource);
                                            if (!string.IsNullOrEmpty(file))
                                            {
                                                PrefetchedList.AddOrUpdate(url, true, (k, v) => true);
                                                //if (!PrefetchedList.TryAdd(url, true)) PrefetchedList.TryUpdate(url, true, false);
                                                count = count - 1;
                                            }
                                        }
                                    }
                                    if (PrefetchingBgWorker.CancellationPending)
                                    {
                                        e.Cancel = true; State = TaskStatus.Canceled; return;
                                    }
                                    Percentage = count == 0 ? 100 : (total - count) / (double)total * 100;
                                    Comments   = $"Prefetching [ {count} / {total}, I:{illusts.Count} / A:{avatars.Count} / T:{page_thumbs.Count} / P:{page_previews.Count} ]";
                                    State      = TaskStatus.Running;
                                    if (ReportProgressSlim is Action)
                                    {
                                        ReportProgressSlim.Invoke(async: false);
                                    }
                                    else if (ReportProgress is Action <double, string, TaskStatus> )
                                    {
                                        ReportProgress.Invoke(Percentage, Comments, State);
                                    }
                                    //await Task.Delay(10);
                                    this.DoEvents();
                                }
                                catch (Exception ex) { ex.ERROR("PREFETCHING"); }
                                finally { if (tasks is SemaphoreSlim && tasks.CurrentCount <= parallels)
                                          {
                                              tasks.Release();
                                          }
                                          this.DoEvents(); await Task.Delay(1); }
                            }).Invoke(async: false);
                        }
                    }
                    this.DoEvents();
                }

                if (PrefetchingBgWorker.CancellationPending)
                {
                    e.Cancel = true; State = TaskStatus.Canceled; return;
                }
                if (count >= 0 && total > 0)
                {
                    Percentage = count == 0 ? 100 : (total - count) / (double)total * 100;
                    Comments   = $"Done [ {count} / {total}, I:{illusts.Count} / A:{avatars.Count} / T:{page_thumbs.Count} / P:{page_previews.Count} ]";
                    //State = TaskStatus.RanToCompletion;
                    //if (ReportProgressSlim is Action) ReportProgressSlim.Invoke(async: false);
                    //else if (ReportProgress is Action<double, string, TaskStatus>) ReportProgress.Invoke(Percentage, Comments, State);
                    //this.DoEvents();
                    $"Prefetching Previews, Avatars, Thumbnails : {Environment.NewLine}  {Comments}".ShowToast("INFO", tag: args.Name ?? Name ?? GetType().Name);
                }
            }
            catch (Exception ex)
            {
                ex.ERROR("PREFETCHING");
                Comments = $"Failed {Comments}";
                State    = TaskStatus.Faulted;
                if (ReportProgressSlim is Action)
                {
                    ReportProgressSlim.Invoke(async: false);
                }
                else if (ReportProgress is Action <double, string, TaskStatus> )
                {
                    ReportProgress.Invoke(Percentage, Comments, State);
                }
            }
            finally
            {
                try
                {
                    GetOriginalImageSize(originals, e);
                    if (ReportProgressSlim is Action)
                    {
                        ReportProgressSlim.Invoke(async: false);
                    }
                    else if (ReportProgress is Action <double, string, TaskStatus> )
                    {
                        ReportProgress.Invoke(Percentage, Comments, State);
                    }
                    this.DoEvents();
                    illusts.Clear();
                    avatars.Clear();
                    page_thumbs.Clear();
                    page_previews.Clear();
                    originals.Clear();
                    needUpdate.Clear();
                }
                catch (Exception ex) { ex.ERROR("PREFETCHED"); }
                if (CanPrefetching is SemaphoreSlim && CanPrefetching.CurrentCount < 1)
                {
                    CanPrefetching.Release();
                }
                LastStartTime = DateTime.Now;
            }
        }