Task.Delay()的行为不符合预期 [英] Task.Delay() not behaving as expected
问题描述
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 Task
s in C# and how to replace Thread
s 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()
中添加async
和await
,但不仅没有添加1秒的延迟,而且仅打印了一行而不是20.When I run this, the test finishes in milliseconds, not in 20 seconds as I would expect. If I replace
Task.Delay()
withThread.Sleep()
, everything works as expected and I get the printout once a second. I have tried addingasync
andawait
intoChattyWriter()
, 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 sameThread
will be blocked for no good reason.推荐答案
Task.Delay
返回必须等待的Task
对象.否则,以下代码将立即执行.因此,您必须将您的方法声明为async
.然后您可以等待Task.Delay
Task.Delay
returns aTask
object on which you have to wait. Otherwise the following code will be executed immediately. Therfore you have to declare your method asasync
. Then you can awaitTask.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屋!