c# – 取消.Net 4.0中的任务延迟

前端之家收集整理的这篇文章主要介绍了c# – 取消.Net 4.0中的任务延迟前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我目前正在尝试在必须以.Net 4.0为目标的程序中实现.Net 4.5的Task.Delay()方法的替代品.我在 this blog找到了以下代码.
  1. /* You can write Task-based asynchronous methods by utilizing a TaskCompletionSource.
  2. A TaskCompletionSource gives you a 'slave' Task that you can manually signal.
  3. Calling SetResult() signals the task as complete,and any continuations kick off. */
  4.  
  5. void Main()
  6. {
  7. for (int i = 0; i < 10000; i++)
  8. {
  9. Task task = Delay (2000);
  10. task.ContinueWith (_ => "Done".Dump());
  11. }
  12. }
  13.  
  14. Task Delay (int milliseconds) // Asynchronous NON-BLOCKING method
  15. {
  16. var tcs = new TaskCompletionSource<object>();
  17. new Timer (_ => tcs.SetResult (null)).Change (milliseconds,-1);
  18. return tcs.Task;
  19. }

任务对我来说都是新手. System.Threading.Timer和TaskCompletionSource对我来说是全新的(截至今天),我正在与他们挣扎.除此之外,我想知道如何在此代码添加CancellationToken功能.我假设我可以像这样在Delay()方法添加一个参数:

  1. Task Delay (int milliseconds,CancellationToken token) // Asynchronous NON-BLOCKING method
  2. {
  3. var tcs = new TaskCompletionSource<object>();
  4. new Timer (_ => tcs.SetResult (null)).Change (milliseconds,-1);
  5. return tcs.Task;
  6. }

…但是,我在哪里放置检查令牌和退出方法的逻辑?在回调的某个地方?这甚至可能吗?

解决方法

我试图尽可能少地更改你的代码,但这是一个工作示例,其行为与Task.Delay相同.

重要的是要注意我使用TrySetCanceled和TrySetResult,因为Timer可以在任务取消后完成.理想情况下,您想要停止计时器.

另请注意,取消的任务将抛出TaskCanceledException

  1. static void Main(string[] args)
  2. {
  3. // A cancellation source that will cancel itself after 1 second
  4. var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(1));
  5.  
  6. try
  7. {
  8. // This will only wait 1 second because as it will be cancelled.
  9. Task t = Delay(5000,cancellationTokenSource.Token);
  10. t.Wait();
  11. Console.WriteLine("The task completed");
  12. }
  13. catch (AggregateException exception)
  14. {
  15. // Expecting a TaskCanceledException
  16. foreach (Exception ex in exception.InnerExceptions)
  17. Console.WriteLine("Exception: {0}",ex.Message);
  18. }
  19. Console.WriteLine("Done");
  20. Console.ReadLine();
  21. }
  22.  
  23. private static Task Delay(int milliseconds,CancellationToken token)
  24. {
  25. var tcs = new TaskCompletionSource<object>();
  26. token.Register(() => tcs.TrySetCanceled());
  27. Timer timer = new Timer(_ => tcs.TrySetResult(null));
  28. timer.Change(milliseconds,-1);
  29. return tcs.Task;
  30. }

再读一下你的问题.如果您需要Task.Delay并且您的目标是.NET 4.0,那么您应该使用http://www.nuget.org/packages/Microsoft.Bcl.Async/中的Microsoft Async nuget包它包含方法TaskEx.Delay

猜你在找的C#相关文章