取消.Net 4.0中的任务延迟
我目前正在尝试在必须以.Net 4.0为目标的程序中实现.Net 4.5的Task.Delay()
方法的替代品。 我在这个博客上找到了以下代码。
/* You can write Task-based asynchronous methods by utilizing a TaskCompletionSource. A TaskCompletionSource gives you a 'slave' Task that you can manually signal. Calling SetResult() signals the task as complete, and any continuations kick off. */ void Main() { for (int i = 0; i "Done".Dump()); } } Task Delay (int milliseconds) // Asynchronous NON-BLOCKING method { var tcs = new TaskCompletionSource(); new Timer (_ => tcs.SetResult (null)).Change (milliseconds, -1); return tcs.Task; }
Tasks
对我来说相当新鲜。 System.Threading.Timer
和TaskCompletionSource
对我来说是全新的(截至今天),我正在与他们挣扎。 除此之外,我想知道如何在此代码中添加CancellationToken
function。 我假设我可以像这样在Delay()
方法中添加一个参数:
Task Delay (int milliseconds, CancellationToken token) // Asynchronous NON-BLOCKING method { var tcs = new TaskCompletionSource(); new Timer (_ => tcs.SetResult (null)).Change (milliseconds, -1); return tcs.Task; }
…但是,我在哪里放置检查令牌和退出方法的逻辑? 在回调的某个地方? 这有可能吗?
我试图尽可能少地更改你的代码,但这是一个工作示例,其行为与Task.Delay相同。
重要的是要注意我使用TrySetCanceled
和TrySetResult
因为Timer可以在任务取消后完成。 理想情况下,您想要停止计时器。
另请注意,取消的任务将抛出TaskCanceledException
static void Main(string[] args) { // A cancellation source that will cancel itself after 1 second var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(1)); try { // This will only wait 1 second because as it will be cancelled. Task t = Delay(5000, cancellationTokenSource.Token); t.Wait(); Console.WriteLine("The task completed"); } catch (AggregateException exception) { // Expecting a TaskCanceledException foreach (Exception ex in exception.InnerExceptions) Console.WriteLine("Exception: {0}", ex.Message); } Console.WriteLine("Done"); Console.ReadLine(); } private static Task Delay(int milliseconds, CancellationToken token) { var tcs = new TaskCompletionSource
再读一下你的问题。 如果您需要Task.Delay并且您的目标是.NET 4.0,那么您应该使用来自http://www.nuget.org/packages/Microsoft.Bcl.Async/的Microsoft Async nuget包它包含方法TaskEx.Delay
像这样 :
token.Register(() => tcs.TrySetCancelled());
在这里,您是一个防止垃圾收集器处理计时器的版本
public static Task Delay(int milliseconds, CancellationToken token) { var tcs = new TaskCompletionSource