C# Task.Delay()的行为不符合预期
Task.Delay()的行为不符合预期,或者说我不理解它应该做什么。我正试图了解C#中的C# Task.Delay()的行为不符合预期,c#,multithreading,task-parallel-library,C#,Multithreading,Task Parallel Library,Task.Delay()的行为不符合预期,或者说我不理解它应该做什么。我正试图了解C#中的Tasks以及如何在实现中替换Threads 我想做的是这样的: 虽然是真的 打印一行 等一下 如果条件满足,则退出循环,否则继续循环 我已经用线程很好地实现了这一点,但所有的酷孩子都说我应该使用任务,不要碰线程 因此,对于代码,我有以下内容(忽略[Test]——这只是一种方便的尝试方式) 当我运行它时,测试在毫秒内完成,而不是像我预期的那样在20秒内完成。如果我将Task.Delay()替换为Th
Task
s以及如何在实现中替换Thread
s
我想做的是这样的:
- 虽然是真的
- 打印一行
- 等一下
- 如果条件满足,则退出循环,否则继续循环
[Test]
——这只是一种方便的尝试方式)
当我运行它时,测试在毫秒内完成,而不是像我预期的那样在20秒内完成。如果我将Task.Delay()
替换为Thread.Sleep()
,那么一切都会按预期工作,我每秒会得到一次打印输出。我尝试将async
和wait
添加到ChattyWriter()
中,但它不仅没有添加1秒延迟,而且只打印了一行而不是20行
我做错了什么
也许这有助于描述我在做什么:我的项目使用外部API(RESTful),在我请求执行一些任务后,我需要轮询API以检查任务是否已完成。外部任务可以长时间运行:1-15分钟。所以我需要在检查是否完成之间有一些延迟。而且可能有许多不同的并发进程与多个外部任务一起执行。我理解,如果我在轮询时使用Thread.Sleep()
,同一线程上的其他进程将无缘无故被阻止。任务延迟(1000)代码>创建一个异步任务,该任务将在一秒钟后完成,但当前方法的执行将并行继续
为了等待任务首先完成,您可以替换
Task.Delay(1000);
与
Task.Delay
返回必须等待的Task
对象。否则,将立即执行以下代码。因此,必须将方法声明为async
。然后您可以等待任务。延迟
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);
...
}
}
你必须以某种方式中断你的呼叫线程。单元测试将终止,后台线程也将终止。但是如果从UI调用此方法,UI将不会被阻止
通过在异步方法上调用Wait
,最终将导致死锁。有关更多信息,请参阅。任务。延迟()实际上创建了一个任务,因此您只需等待它
试试这个
public static void ChattyWriter()
{
int count = 0;
while (true)
{
var message = String.Format("Chatty Writer number {0}", count);
Console.WriteLine(message);
count++;
var t = Task.Delay(1000);
t.Wait();
if (count >= 20)
{
break;
}
}
}
我试过了,它只给了我打印出来的第一行,然后就完成了。这可能是因为你的主线程(测试例程)可以继续运行,而你看不到其余的,因为程序终止了。如果您从UI按钮启动线程,UI仍然会有响应。您在这一点上绝对正确!我已将Thread.Sleep(20000)
放在测试例程中,并得到了预期结果。@trailmax但这会创建一个在一秒钟内不执行任何操作的新任务。一个更好的方法是简单地调用线程。睡眠(1000)。@ TrILMAX,而我的帖子解释了为什么<代码>任务。Delay < /代码>不起作用,请考虑使用所描述的方法,这更有效。方法之间有主要区别吗?我总是认为async await
只是编译器的一种语法糖?@Alberto如果我在同一个线程上运行多个任务(根据MSDN,这是可能的),并调用thread.Sleep()
,这将阻止其他任务。如果我错了,请纠正我。Task.Delay有一个优点,即在传递CancellationToken时它是可取消的。Task.Delay返回任务的主要原因是,您可以调用wait。您的答案与@w0lf的答案相同
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);
...
}
}
public static void ChattyWriter()
{
int count = 0;
while (true)
{
var message = String.Format("Chatty Writer number {0}", count);
Console.WriteLine(message);
count++;
var t = Task.Delay(1000);
t.Wait();
if (count >= 20)
{
break;
}
}
}