Calculate Time Remaining

后端 未结 16 2648
一生所求
一生所求 2020-12-04 08:22

What\'s a good algorithm for determining the remaining time for something to complete? I know how many total lines there are, and how many have completed already, how shoul

16条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-04 09:22

    I prefer System.Threading.Timer rather than System.Diagnostics.Stopwatch.

    System.Threading.Timer, which executes a single callback method on a thread pool thread

    The following code is an example of a calculating elapsed time with Threading.Timer.

    public class ElapsedTimeCalculator : IDisposable
    {
        private const int ValueToInstantFire = 0;
    
        private readonly Timer timer;
        private readonly DateTime initialTime;
    
        public ElapsedTimeCalculator(Action action)
        {
            timer = new Timer(new TimerCallback(_ => action(ElapsedTime)));
            initialTime = DateTime.UtcNow;
        }
    
        // Use Timeout.Infinite if you don't want to set period time.
        public void Fire() => timer.Change(ValueToInstantFire, Timeout.Infinite);
    
        public void Dispose() => timer?.Dispose();
    
        private TimeSpan ElapsedTime => DateTime.UtcNow - initialTime;
    }
    

    BTW You can use System.Reactive.Concurrency.IScheduler (scheduler.Now.UtcDateTime) instead of using DateTime directly, if you would like to mock and virtualize the datetime for unit tests.

    public class PercentageViewModel : IDisposable
    {
        private readonly ElapsedTimeCalculator elapsedTimeCalculator;
    
        public PercentageViewModel()
        {
           elapsedTimeCalculator = new ElapsedTimeCalculator(CalculateTimeRemaining))
        }
    
        // Use it where You would like to estimate time remaining.
        public void UpdatePercentage(double percent)
        {
            Percent = percent;
            elapsedTimeCalculator.Fire();
        }
    
        private void CalculateTimeRemaining(TimeSpan timeElapsed)
        {
            var timeRemainingInSecond = GetTimePerPercentage(timeElapsed.TotalSeconds) * GetRemainingPercentage;
    
            //Work with calculated time...  
        }
    
        public double Percent { get; set; }
    
        public void Dispose() => elapsedTimeCalculator.Dispose();
    
        private double GetTimePerPercentage(double elapsedTime) => elapsedTime / Percent;
    
        private double GetRemainingPercentage => 100 - Percent; 
    }
    

提交回复
热议问题