/// <summary>
        /// 开始下载,若获取大小失败,则会抛出异常
        /// </summary>
        public async ValueTask DownloadAsync(CancellationToken token)
        {
            StatusSubject.OnNext(@"正在获取下载文件大小...");
            FileSize = await GetContentLengthAsync(token);             //总大小

            TempDir = EnsureDirectory(TempDir);
            var list = GetFileRangeList();

            var opQueue = new OperationQueue(1);

            Current = 0;
            Last    = 0;
            try
            {
                using var speedMonitor = CreateSpeedMonitor();

                StatusSubject.OnNext(@"正在下载...");
                await list.Select(info =>
                                  // ReSharper disable once AccessToDisposedClosure
                                  opQueue.Enqueue(1, () => GetStreamAsync(info, token))
                                  .ToObservable()
                                  .SelectMany(res => WriteToFileAsync(res.Item1, res.Item2, token))
                                  ).Merge();

                StatusSubject.OnNext(@"下载完成,正在合并文件...");
                Current = 0;
                await MergeFilesAsync(list, token);
            }
            catch (OperationCanceledException)
            {
                StatusSubject.OnNext(@"下载已取消");
                throw;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, @"下载出错");
                StatusSubject.OnNext(@"下载出错");
            }
            finally
            {
                await opQueue.ShutdownQueue();

                opQueue.Dispose();

                Task.Run(async() =>
                {
                    foreach (var range in list)
                    {
                        await DeleteFileWithRetryAsync(range.FileName);
                    }
                }, CancellationToken.None).NoWarning();
            }
        }
示例#2
0
        public Subject(int id, Person person, bool coronatestPositive, DateTime coronaTest, Symptoms symtoms, DateTime firstSigns, string extraInformation, StatusSubject statusSubject, string dossierNr)
        {
            Id                 = id;
            Person             = person;
            CoronatTstPositive = coronatestPositive;
            CoronaTest         = coronaTest;
            Symtoms            = symtoms;
            FirstSigns         = firstSigns;
            ExtraInformation   = extraInformation;

            StatusSubject = statusSubject;
            DossierNr     = dossierNr;
        }
示例#3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ProjectionBase{TState}"/> class.
        /// </summary>
        /// <param name="eventStore">Event store service</param>
        /// <param name="log">Log service</param>
        /// <param name="activeTimeline">Timeline service</param>
        /// <param name="streamLocator">Stream locator</param>
        public ProjectionBase(IEventStore <IAggregate> eventStore, ILog log, ITimeline activeTimeline, IStreamLocator streamLocator)
        {
            EventStore         = eventStore;
            Log                = log;
            ActiveTimeline     = activeTimeline;
            _streamLocator     = streamLocator;
            CancellationSource = new RepeatableCancellationTokenSource();
            _start             = new Lazy <Task>(() => Task.Run(Start));
            var options = new DataflowOptions {
                RecommendedParallelismIfMultiThreaded = 1
            };

            Build = new BuildFlow(options, this);

            StatusSubject.Where(s => s != Sleeping)
            .Subscribe(s => Log?.Info($"[{Timeline}]{GetType().GetFriendlyName()}/{RuntimeHelpers.GetHashCode(this)}/ : {s.ToString()}"));
        }