public virtual Task <TimeSpan> GetUptimeAsync(TimeSpan updatePeriod, CancellationToken cancellationToken = default) { var computed = Computed.GetCurrent(); Task.Delay(updatePeriod, cancellationToken).ContinueWith(_ => computed !.Invalidate(), cancellationToken); return(Task.FromResult(DateTime.UtcNow - _startTime)); }
public virtual Task <string> GetMomentsAgo(DateTime time) { // TODO: Make this method stop leaking some memory due to timers that don't die unless timeout var delta = DateTime.UtcNow - time.DefaultKind(DateTimeKind.Utc).ToUniversalTime(); if (delta < TimeSpan.Zero) { delta = TimeSpan.Zero; } var(unit, unitName) = GetMomentsAgoUnit(delta); var unitCount = (int)(delta.TotalSeconds / unit.TotalSeconds); string result; if (unitCount == 0 && unit == TimeSpan.FromSeconds(1)) { result = $"just now"; } else { var pluralizedUnitName = Pluralize.Format(unitName, unitCount); result = $"{unitCount} {pluralizedUnitName} ago"; } // Invalidate the result when it's supposed to change var delay = TrimInvalidationDelay((unitCount + 1) * unit - delta + TimeSpan.FromMilliseconds(100)); Computed.GetCurrent() !.Invalidate(delay, false); return(Task.FromResult(result)); }
public virtual Task <double> GetUptime(double updatePeriod, CancellationToken cancellationToken = default) { var computed = Computed.GetCurrent(); Task.Delay(TimeSpan.FromSeconds(updatePeriod), default) .ContinueWith(_ => computed !.Invalidate(), CancellationToken.None); return(Task.FromResult((DateTime.UtcNow - _startTime).TotalSeconds)); }
public virtual Task <TimeSpan> GetUptimeAsync(TimeSpan updatePeriod, CancellationToken cancellationToken = default) { var computed = Computed.GetCurrent(); var time = DateTime.UtcNow; time = time.AddYears(100); //time.Days += 42; Task.Delay(updatePeriod, default) .ContinueWith(_ => computed !.Invalidate(), CancellationToken.None); return(Task.FromResult(time - _startTime)); }
public virtual Task <long> GetActiveUserCountAsync(CancellationToken cancellationToken = default) { var channelHub = _publisher.ChannelHub; var userCount = (long)channelHub.ChannelCount; var c = Computed.GetCurrent(); Task.Run(async() => { do { await Task.Delay(1000, default).ConfigureAwait(false); } while (userCount == channelHub.ChannelCount); c !.Invalidate(); }, default).Ignore();
public virtual async Task <DateTime> GetTimeAsync() { WriteLine($"* {nameof(GetTimeAsync)}()"); // That's how you "pull" the computed that is going to // store the result of this computation var computed = Computed.GetCurrent(); // We just start this task here, but don't await for its result Task.Delay(TimeSpan.FromSeconds(0.1)).ContinueWith(_ => { computed !.Invalidate(); WriteLine($"! {nameof(GetTimeAsync)}() -> invalidated"); }).Ignore(); return(DateTime.Now); }
public virtual async Task <bool> DeleteAsync(User user, CancellationToken cancellationToken = default) { Computed.GetCurrent().Should().BeNull(); await using var dbContext = DbContextFactory.CreateDbContext(); dbContext.Users.Remove(user); try { await dbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false); Invalidate(user); return(true); } catch (DbUpdateConcurrencyException) { return(false); } }
protected virtual Task <DirectBitmap> GetScreenshot(CancellationToken cancellationToken = default) { // Captures a full-resolution screenshot; the code here is optimized // to produce the next screenshot in advance & instantly return the prev. one. var currentProducer = Task.Run(TakeScreenshot, default); var prevProducer = Interlocked.Exchange(ref _currentProducer, currentProducer) ?? currentProducer; Computed.GetCurrent() !.Invalidated += c => Task.Delay(1000).ContinueWith(_ => { // Let's dispose the bitmap in 1 second after invalidation var computed = (IComputed <DirectBitmap>)c; if (computed.HasValue) { computed.Value.Dispose(); } }); return(prevProducer); }
protected virtual Task <Bitmap> GetScreenshotAsync(CancellationToken cancellationToken = default) { // This method takes a full-resolution screenshot var(w, h) = (_displayDimensions.Width, _displayDimensions.Height); var bScreen = new Bitmap(w, h); using var gScreen = Graphics.FromImage(bScreen); gScreen.CopyFromScreen(0, 0, 0, 0, bScreen.Size); Computed.GetCurrent() !.Invalidated += c => Task.Delay(2000).ContinueWith(_ => { // Let's dispose these values in 2 seconds var computed = (IComputed <Bitmap>)c; if (computed.HasValue) { computed.Value.Dispose(); } }); return(Task.FromResult(bScreen)); }
public virtual Task <string> GetMomentsAgoAsync(DateTime time) { var delta = Clock.Now.ToDateTime() - time; if (delta < TimeSpan.Zero) { delta = TimeSpan.Zero; } var(unit, unitName) = GetMomentsAgoUnit(delta); var unitCount = (int)(delta.TotalSeconds / unit.TotalSeconds); var pluralizedUnitName = Pluralize.Format(unitName, unitCount); var result = $"{unitCount} {pluralizedUnitName} ago"; // Invalidate the result when it's supposed to change var delay = (unitCount + 1) * unit - delta; var computed = Computed.GetCurrent(); Task.Delay(delay, default).ContinueWith(_ => computed !.Invalidate()).Ignore(); return(Task.FromResult(result)); }
protected override Action <IInvocation> CreateHandler <T>( IInvocation initialInvocation, MethodDef methodDef) { var computeMethodDef = (ComputeMethodDef)methodDef; var function = CreateFunction <T>(computeMethodDef); return(invocation => { var input = computeMethodDef.CreateInput(function, (AbstractInvocation)invocation); var arguments = input.Arguments; var cancellationTokenIndex = computeMethodDef.CancellationTokenArgumentIndex; var cancellationToken = cancellationTokenIndex >= 0 ? (CancellationToken)arguments[cancellationTokenIndex] : default; // Invoking the function var usedBy = Computed.GetCurrent(); // InvokeAndStripAsync allows to get rid of one extra allocation // of a task stripping the result of regular InvokeAsync. var task = function.InvokeAndStripAsync(input, usedBy, null, cancellationToken); if (cancellationTokenIndex >= 0) { // We don't want memory leaks + unexpected cancellation later arguments[cancellationTokenIndex] = NoCancellationTokenBoxed; } if (methodDef.ReturnsValueTask) { // ReSharper disable once HeapView.BoxingAllocation invocation.ReturnValue = new ValueTask <T>(task); } else { invocation.ReturnValue = task; } }); }
public virtual Task <DateTime> GetUtcNow(TimeSpan updatePeriod) { Computed.GetCurrent() !.Invalidate(TrimInvalidationDelay(updatePeriod)); return(Task.FromResult(Clock.Now.ToDateTime())); }