Calculate Time Remaining

后端 未结 16 2565
一生所求
一生所求 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:19

    I made this and it works quite good, feel free to change the method signature according to your variable types or also to the return type, probably you would like to get the TimeSpan object or just the seconds...

        /// <summary>
        /// Calculates the eta.
        /// </summary>
        /// <param name="processStarted">When the process started</param>
        /// <param name="totalElements">How many items are being processed</param>
        /// <param name="processedElements">How many items are done</param>
        /// <returns>A string representing the time left</returns>
        private string CalculateEta(DateTime processStarted, int totalElements, int processedElements)
        {
            int itemsPerSecond = processedElements / (int)(processStarted - DateTime.Now).TotalSeconds;
            int secondsRemaining = (totalElements - processedElements) / itemsPerSecond;
    
            return new TimeSpan(0, 0, secondsRemaining).ToString();
        }
    

    You will require to initialize a DateTime variable when the processing starts and send it to the method on each iteration.

    Do not forget that probably your window will be locked if the process is quite long, so when you place the return value into a control, don't forget to use the .Refresh() method of it.

    If you are using threads then you can attempt to set the text using the Invoke(Action) method, would be easier to use this extension method to archieve it easily.

    If you use a console application, then you should not have problems displaying the output line by line.

    Hope it helps someone.

    0 讨论(0)
  • 2020-12-04 09:19

    I already knew the percentage complete & time elapsed, so this helped me:

    TimeElapsed * ((100 - %complete) / %complete) = TimeRemaining

    I then updated this value every time %complete changed, giving me a constant varying ETA.

    0 讨论(0)
  • 2020-12-04 09:19

    PowerShell function

    function CalculateEta([datetime]$processStarted, [long]$totalElements, [long]$processedElements) {
        $itemsPerSecond = $processedElements / [DateTime]::Now.Subtract($processStarted).TotalSeconds
        $secondsRemaining = ($totalElements - $processedElements) / $itemsPerSecond
    
        return [TimeSpan]::FromSeconds($secondsRemaining)
    }
    
    0 讨论(0)
  • 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<TimeSpan> 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; 
    }
    
    0 讨论(0)
提交回复
热议问题