Как поставить задачу в спящий режим (или задержку) в C# 4.0?
991 9
9 ответов:
можно использовать
TimerсоздатьDelayметод в 4.0:public static Task Delay(double milliseconds) { var tcs = new TaskCompletionSource<bool>(); System.Timers.Timer timer = new System.Timers.Timer(); timer.Elapsed+=(obj, args) => { tcs.TrySetResult(true); }; timer.Interval = milliseconds; timer.AutoReset = false; timer.Start(); return tcs.Task; }
использовать Microsoft.Bcl.Асинхронный пакет от NuGet, он имеет
TaskEx.Delay.
using System; using System.Threading; using System.Threading.Tasks; class Program { static void Main() { Delay(2000).ContinueWith(_ => Console.WriteLine("Done")); Console.Read(); } static Task Delay(int milliseconds) { var tcs = new TaskCompletionSource<object>(); new Timer(_ => tcs.SetResult(null)).Change(milliseconds, -1); return tcs.Task; } }из раздела Как реализовать задачу.Задержка в 4.0
Ниже приведен код и пример жгута проводов для отменяемой задачи.Задержка реализации. Вы, вероятно, заинтересованы в
Delayметод.:using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DelayImplementation { class Program { static void Main(string[] args) { System.Threading.CancellationTokenSource tcs = new System.Threading.CancellationTokenSource(); int id = 1; Console.WriteLine(string.Format("Starting new delay task {0}. This one will be cancelled.", id)); Task delayTask = Delay(8000, tcs.Token); HandleTask(delayTask, id); System.Threading.Thread.Sleep(2000); tcs.Cancel(); id = 2; System.Threading.CancellationTokenSource tcs2 = new System.Threading.CancellationTokenSource(); Console.WriteLine(string.Format("Starting delay task {0}. This one will NOT be cancelled.", id)); var delayTask2 = Delay(4000, tcs2.Token); HandleTask(delayTask2, id); System.Console.ReadLine(); } private static void HandleTask(Task delayTask, int id) { delayTask.ContinueWith(p => Console.WriteLine(string.Format("Task {0} was cancelled.", id)), TaskContinuationOptions.OnlyOnCanceled); delayTask.ContinueWith(p => Console.WriteLine(string.Format("Task {0} was completed.", id)), TaskContinuationOptions.OnlyOnRanToCompletion); } static Task Delay(int delayTime, System.Threading.CancellationToken token) { TaskCompletionSource<object> tcs = new TaskCompletionSource<object>(); if (delayTime < 0) throw new ArgumentOutOfRangeException("Delay time cannot be under 0"); System.Threading.Timer timer = null; timer = new System.Threading.Timer(p => { timer.Dispose(); //stop the timer tcs.TrySetResult(null); //timer expired, attempt to move task to the completed state. }, null, delayTime, System.Threading.Timeout.Infinite); token.Register(() => { timer.Dispose(); //stop the timer tcs.TrySetCanceled(); //attempt to mode task to canceled state }); return tcs.Task; } } }
расширение идеи из этого ответ:
new AutoResetEvent(false).WaitOne(1000);
во многих случаях явный AutoResetEvent лучше, чем поток.Сон.)(..
AutoResetEvent pause = new AutoResetEvent(false); Task timeout = Task.Factory.StartNew(()=>{ pause.WaitOne(1000, true); });надеюсь, что это помогает
можно скачать Visual Studio Async CTP и использовать TaskEx.Задержка
public static void DelayExecute(double delay, Action actionToExecute) { if (actionToExecute != null) { var timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(delay) }; timer.Tick += (delegate { timer.Stop(); actionToExecute(); }); timer.Start(); } }
вот краткая реализация на основе таймера с правильной очисткой:
var wait = new TaskCompletionSource<bool>(); using (new Timer(_ => wait.SetResult(false), null, delay, Timeout.Infinite)) await wait.Task;чтобы использовать этот код на .NET 4.0, вам нужно Microsoft.Bcl.Асинхронный пакета NuGet.
Comments