如何在 C# 4.0 中让任务进入睡眠(或延迟)状态?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15341962/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to put a task to sleep (or delay) in C# 4.0?
提问by Fulproof
There is Task.Delayin .NET 4.5
.NET 4.5 中 有Task.Delay
How can I do the same in .NET 4.0?
我如何在 .NET 4.0 中做同样的事情?
采纳答案by Servy
You can use a Timer
to create a Delay
method in 4.0:
您可以使用 a在 4.0 中Timer
创建Delay
方法:
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;
}
回答by QrystaL
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;
}
}
From the section How to implement Task.Delay in 4.0
回答by DVD
You can download the Visual Studio Async CTPand use TaskEx.Delay
您可以下载Visual Studio Async CTP并使用 TaskEx.Delay
回答by Eli Arbel
Use the Microsoft.Bcl.Asyncpackage from NuGet, it has TaskEx.Delay
.
使用来自 NuGet的Microsoft.Bcl.Async包,它具有TaskEx.Delay
.
回答by Gusdor
Below is the code and sample harness for a cancellable Task.Delay implementation. You are likely interested in the Delay
method.:
下面是可取消 Task.Delay 实现的代码和示例工具。您可能对该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;
}
}
}
回答by f.capet
In many cases, a sheer AutoResetEvent is better than a Thread.Sleep()...
在许多情况下,纯粹的 AutoResetEvent 比 Thread.Sleep()...
AutoResetEvent pause = new AutoResetEvent(false);
Task timeout = Task.Factory.StartNew(()=>{
pause.WaitOne(1000, true);
});
hope that it helps
希望它有帮助
回答by WndRnr
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();
}
}
回答by Edward Brey
Here's a succinct, timer-based implementation with proper cleanup:
这是一个简洁的、基于计时器的、经过适当清理的实现:
var wait = new TaskCompletionSource<bool>();
using (new Timer(_ => wait.SetResult(false), null, delay, Timeout.Infinite))
await wait.Task;
To use this code on .NET 4.0, you need the Microsoft.Bcl.AsyncNuGet package.
要在 .NET 4.0 上使用此代码,您需要Microsoft.Bcl.AsyncNuGet 包。