Myślę, że to, co masz, to całkiem niezły Scott.
Jedyny niewielki problem, który moim zdaniem może dotyczyć, polega na tym, że blokujesz wątek w celu wykonania opóźnienia. Oczywiście jest to wątek działający w tle i raczej nie spowoduje problemów, dopóki nie wykonasz wielu takich połączeń jednocześnie (każde z nich będzie wiązało wątek), ale nadal jest prawdopodobnie nieoptymalny.
Zamiast tego sugerowałbym, abyś uwzględnił algorytm w metodzie narzędzia i unikał używania Thread.Sleep.
Jest oczywiście zapewne niezliczone sposoby, aby to zrobić, ale tutaj jest jeden:
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));
}
}
Sposób użycia:
UICallbackTimer.DelayExecution(TimeSpan.FromSeconds(1),
() => textBlock.Text="Done");
Oczywiście można też napisać implementację tej metody DelayExecution który wykorzystuje inne typy timera, takiego jak WPF DispatcherTimer lub klasa WinForms Timer. Nie jestem pewien, jakie byłyby kompromisy między tymi różnymi zegarami. Domyślam się, że czasomierze DispatcherTimer i WinForm nadal działałyby w aplikacjach typu przeciwnego.
EDIT:
Ponownie czytając moją odpowiedź, myślę, że rzeczywiście chciałbym pokusić się o czynnik to pod metodę rozszerzenia, które działa od kontekstu synchronizacji - jeśli myślisz o tym, bardziej ogólne stwierdzenie byłoby że musisz mieć możliwość wysłania pracy z powrotem do kontekstu synchronizacji po pewnym opóźnieniu.
Kontekst synchronizacji ma już metodę post dla pracy w kolejce, której pierwotny rozmówca nie chce blokować po zakończeniu.To, czego potrzebujemy jest to, że wersja stanowisk pracy z opóźnieniem, więc zamiast:
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));
}
}
i zastosowanie:
SynchronizationContext.Current.Post(TimeSpan.FromSeconds(1),
() => textBlock.Text="Done");
Jeśli używasz WPF użyć [DispatcherTimer] (http: // msdn .microsoft.com/en-us/library/system.windows.threading.dispatchertimer.aspx) –