Task.Delay()的行为不符合预期 [英] Task.Delay() not behaving as expected

查看:84
本文介绍了Task.Delay()的行为不符合预期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Task.Delay()的行为不符合预期,或者我不了解它应该做什么.我正在努力弄清C#中的Task s以及如何在实现中替换Thread s.

Task.Delay() not behaving as expected or rather I'm not understanding what it is supposed to do. I'm trying to get my head around Tasks in C# and how to replace Threads in my implementation.

我想做的是这样的:

  • 虽然为真
    • 打印行
    • 稍等片刻,
    • 如果条件满足,请退出循环,否则继续循环
    • While true
      • print a line
      • wait for a second,
      • If condition is satisfied, exit loop, otherwise keep looping

      我已经用Threads很好地实现了,但是所有很酷的孩子都说我应该使用Task,并且不要碰Thread.

      I've got that implemented with Threads fine, but all cool kids say I should be using Task, and don't touch Thread.

      对于代码来说,我有这个(忽略[Test]-这只是一种方便的尝试方法)

      So for the code I have this (Ignore [Test] - this just a convenient way to try out things)

          [Test]
          public void ChattyTask()
          {
              var chattyTask = new Task(ChattyWriter);
              chattyTask.Start();
              chattyTask.Wait();
          }
      
          public void ChattyWriter()
          {
              int count = 0;
              while (true)
              {
                  var message = String.Format("Chatty Writer number {0}", count);
                  Trace.WriteLine(message);
                  count++;
                  Task.Delay(1000);
      
                  if (count >= 20)
                  {
                      break;
                  }
              }
          }
      

      运行此命令时,测试以毫秒为单位完成,而不是我期望的20秒内完成.如果我将Task.Delay()替换为Thread.Sleep(),则一切都会按预期运行,并且每秒输出一次.我曾尝试在ChattyWriter()中添加asyncawait,但不仅没有添加1秒的延迟,而且仅打印了一行而不是20.

      When I run this, the test finishes in milliseconds, not in 20 seconds as I would expect. If I replace Task.Delay() with Thread.Sleep(), everything works as expected and I get the printout once a second. I have tried adding async and await into ChattyWriter(), but not only it did not add a 1 second delay, it only printed only one line instead of 20.

      我在做什么错了?

      可能会有助于描述我在做什么:我的项目使用外部API(RESTful),并且在我要求执行一些任务之后,需要轮询API以检查任务是否已完成.外部任务可以长时间运行:1-15分钟.因此,我需要在检查完成之间有一些延迟.并且可能有多个不同的并发进程通过多个外部任务执行.我了解,如果在轮询时使用Thread.Sleep(),则没有充分理由将阻止同一Thread上的其他进程.

      Probably It'll help to describe what I'm doing: my project works with external API (RESTful) and after I request some tasks to happen, I need to poll the API to check if the task has been completed. External tasks can be long running: 1-15 minutes. So I need some delay between checking for completion. And there could be many different concurrent processes executed with multiple external tasks. I understand, that if I use Thread.Sleep() when polling, other processes on the same Thread will be blocked for no good reason.

      推荐答案

      Task.Delay返回必须等待的Task对象.否则,以下代码将立即执行.因此,您必须将您的方法声明为async.然后您可以等待Task.Delay

      Task.Delay returns a Task object on which you have to wait. Otherwise the following code will be executed immediately. Therfore you have to declare your method as async. Then you can await Task.Delay

      public async Task ChattyWriter()
      {
          int count = 0;
          while (true)
          {
              var message = String.Format("Chatty Writer number {0}", count);
              Trace.WriteLine(message);
              count++;
              await Task.Delay(1000);
                 ...
          }
      }
      

      您必须以某种方式中断您的调用线程.单元测试将终止,后台线程也将终止.但是,如果您从用户界面调用此方法,则用户界面不会被阻塞.

      You have to interrupt your calling thread somehow. The unit test would terminate and the background thread as well. But if you call this method from the UI, the UI will not get blocked.

      通过在异步方法上调用Wait,您将最终陷入死锁.有关更多信息,请参见此处.

      By calling Wait on an asynchronous method you will end up with a deadlock. See here for more information.

      这篇关于Task.Delay()的行为不符合预期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆