Creo que lo que tienes es bastante bueno Scott.
El único problema leve que creo que algunos podrían tener con él, es que está bloqueando un hilo para ejecutar su retraso. Por supuesto, se trata de un hilo de fondo, y es poco probable que cause problemas a menos que ejecutes muchas de estas llamadas al mismo tiempo (cada una atando un hilo), pero probablemente aún no sea óptimo.
En su lugar, le sugiero que factorice el algoritmo en un método de utilidad, y evite el uso de Thread.Sleep.
Obviamente hay probablemente innumerables maneras de hacer esto, pero aquí está uno:
public static class UICallbackTimer
{
public static void DelayExecution(TimeSpan delay, Action action)
{
System.Threading.Timer timer = null;
SynchronizationContext context = SynchronizationContext.Current;
timer = new System.Threading.Timer(
(ignore) =>
{
timer.Dispose();
context.Post(ignore2 => action(), null);
}, null, delay, TimeSpan.FromMilliseconds(-1));
}
}
de usar:
UICallbackTimer.DelayExecution(TimeSpan.FromSeconds(1),
() => textBlock.Text="Done");
Por supuesto, también podría escribir una implementación de este método DelayExecution que utiliza otros tipos de temporizador como el WPF DispatcherTimer o la clase WinForms Timer. No estoy seguro de cuáles serían las compensaciones de estos varios temporizadores. Creo que los temporizadores de DispatcherTimer y WinForm seguirían funcionando en aplicaciones del tipo opuesto.
EDIT:
Releyendo mi respuesta, creo que en realidad estaría tentado a este factor en un método de extensión que trabaja en contextos de sincronización - si se piensa en ello, una declaración más general sería que necesita poder volver a publicar el trabajo en un contexto de sincronización después de un cierto retraso.
El SynchronizationContext ya tiene un método de publicación para el trabajo en cola, que el llamador original no desea bloquear al finalizar.Lo que necesitamos es una versión de este que los puestos de trabajo después de un retraso, por lo que en su lugar:
public static class SyncContextExtensions
{
public static void Post(this SynchronizationContext context, TimeSpan delay, Action action)
{
System.Threading.Timer timer = null;
timer = new System.Threading.Timer(
(ignore) =>
{
timer.Dispose();
context.Post(ignore2 => action(), null);
}, null, delay, TimeSpan.FromMilliseconds(-1));
}
}
y uso:
SynchronizationContext.Current.Post(TimeSpan.FromSeconds(1),
() => textBlock.Text="Done");
Si está utilizando usar WPF [DispatcherTimer] (http: // MSDN .microsoft.com/es-us/library/system.windows.threading.dispatchertimer.aspx) –