2010-03-01 4 views
5

Tengo algunos temporizadores que miden el tiempo para ejecutar el código.¿Cómo estimar el tiempo de finalización del método en WinForms para informar adecuadamente al usuario sobre la hora prevista de finalización?

DateTime startTimeFunctionTotal = DateTime.Now; 
    for (int i = 0; i < array.Count; i++) { 
     DateTime startTimeFunction = DateTime.Now; 
     //some code here 

      DateTime stopTimeFunction = DateTime.Now; 
      TimeSpan durationTimeFunction = stopTimeFunction - startTimeFunction ; 

} 
DateTime stopTimeFunctionTotal = DateTime.Now; 
TimeSpan durationTimeFunctionTotal = stopTimeFunctionTotal - startTimeFunctionTotal ; 

Está permitido (aún mejor) si el tiempo predicho cambia de acuerdo a más datos (cada lazo que hay más datos de modo de predicción debe ser más exactos).

Me gustaría dar al usuario un tiempo de finalización previsto (tanto el tiempo como 15 minutos y 10:56).

+0

¿Cuál es su pregunta aquí? – Gabe

+0

Mi pregunta era cómo hacer cálculos matemáticos en TimeSpans, y DateTimes para que muestre el tiempo y la hora de finalización correctamente. – MadBoy

+0

Si alguna vez averigua cómo predecir con exactitud el momento en que algo finaliza, venda esta solución a Microsoft, para que podamos terminar con esto: http://xkcd.com/612/ – Powerlord

Respuesta

3

Suponiendo que cada acción en su sentencia for tiene aproximadamente la misma cantidad de tiempo:

List<TimeSpan> timeSpans = new List<TimeSpan>(); 
for(int i = 0; i < array.Count; i++) 
{ 
    Stopwatch watch = Stopwatch.StartNew(); 
    //do stuff 
    timeSpans.Add(watch.Elapsed); 
    long ticksLeft = timeSpans.Sum(ts => ts.Ticks) * (array.Count - i)/timeSpans.Count; 
    Console.WriteLine("Left: " + new TimeSpan(ticksLeft)); 
    Console.WriteLine("Finished in: " + 
     DateTime.Now.AddTicks(ticksLeft)); 
} 

para ir con el uso mediana:

long ticksLeft = timeSpans.OrderBy(ts => ts.Ticks) 
    .ElementAt(timeSpans.Count/2).Ticks * (array.Count - i); 
+0

Probándolo. Hasta ahora todo bien :) – MadBoy

+0

Parece muy bueno. ¿Qué propones si hay un poco más de diferencias en el tiempo (como 1 segundo aquí, 5 segundos allí, 3 segundos aquí). Tiene un poco de problema para hacer que el tiempo sea preciso. Sé que la estimación es una estimación, pero tal vez podría modificarse un poco. – MadBoy

+0

@MadBoy: Puedes ir con la mediana. según lo sugerido por nobugz, actualizaré mi respuesta con él. Si esto no funciona, debe indicar cuántas transacciones y cuánto tiempo tomará, y veré si puedo hacer algo para descartar valores. Pero estas cosas probablemente variarán ampliamente según la máquina. –

1

Para obtener una mejor representación del tiempo para el rendimiento del código (en un buen TimeSpan) eche un vistazo al System.Diagnostics.StopWatch.

Funciona como usted esperaría: Start() para comenzar el cronometraje, Stop() para detenerse. Leer Elapsed para obtener una TimeSpan del tiempo empleado, o ElapsedTicks para la medición más precisa (a TimeSpan.Ticks = 1,0 x 10 -9 seg, o 100 nano-sec; ElapsedTicks es variable y es relativa a la StopWatch.Frequency de 1-sec /valor).

2

Puede hacer una suposición de auto-corrección, como siempre y cuando haya suficientes operaciones que puedan cronometrarse individualmente y que cada una tome aproximadamente la misma cantidad de tiempo. Comience con una suposición y multiplique por el número de operaciones a realizar. Mida el tiempo de la siguiente operación y agréguelo a una lista. Haga una nueva suposición tomando el promedio de los tiempos en esta lista y multiplíquelo por el número de operaciones restantes.

Su estimación será más precisa a medida que obtenga más muestras de tiempo. Y su barra de progreso siempre alcanzará el 100% (+/- un poquito). Tomando la mediana en lugar del promedio es mejor, elimina los valores atípicos debido a la actividad repentina en su máquina por otros procesos. Y deseará descartar medidas antiguas en la lista, mantener solo 10 a 20 es suficiente. Guarde más muestras si el tiempo de operación es más variable.

+0

¿Cuidar para mostrar un ejemplo de cómo abordar esto?El problema más grande que tengo con Math en esto, cómo dividir, multiplicar etc. en TimeSpans y fechas. – MadBoy

+0

Simplemente haga su suposición un int o largo, la cantidad de milisegundos o microsegundos por operación. Convierta a TimeSpan solo en el código de UI. –

+0

¿Consideraría el ejemplo de Yuriy como uno bueno? Parece estar demasiado lejos (incluso con 1000 muestras). – MadBoy

Cuestiones relacionadas