几乎所有有关C#异步编程的介绍都警告不要使用Sleep指令,因为它会阻塞整个线程。
但是我发现在睡眠期间,正在提取并执行队列中的任务。参见:
using System;
using System.Threading.Tasks;
namespace TestApp {
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Main");
Program.step1();
for (int i = 0; i < 6; i++) {
System.Threading.Thread.Sleep(200);
Console.WriteLine("Sleep-Loop");
}
}
private static async void step1() {
await Task.Delay(400);
Console.WriteLine("Step1");
Program.step2();
}
private static async void step2() {
await Task.Delay(400);
Console.WriteLine("Step2");
}
}
}
输出:
Main
Sleep-Loop
Sleep-Loop
Step1
Sleep-Loop
Sleep-Loop
Step2
Sleep-Loop
Sleep-Loop
我的问题:
答案 0 :(得分:2)
在C#7.3中,您可以有一个异步入口点,我建议使用它。
一些注意事项:
Task.WhenAll
修改后的示例
static async Task Main(string[] args)
{
Console.WriteLine("Start Task");
var task = Program.step1();
for (int i = 0; i < 6; i++)
{
await Task.Delay(100);
Console.WriteLine("Sleep-Loop");
}
Console.WriteLine("waiting for the task to finish");
await task;
Console.WriteLine("finished");
Console.ReadKey();
}
private static async Task step1()
{
await Task.Delay(1000);
Console.WriteLine("Step1");
await Program.step2();
}
private static async Task step2()
{
await Task.Delay(1000);
Console.WriteLine("Step2");
}
请务必注意,任务不是线程,并且async
不是并行的,但是可以。
10次中的9次是IO绑定工作使用操作系统IO完成端口,以便释放线程。它具有可扩展性和ui响应功能。
如果您不做任何IO工作,那么实际上根本不需要async
await
模式,因此,这种cpu工作可能应该被包装在{{ 1}}。没有包装在Task.Run
方法中。
在这一点上,还需要注意的是,仅使用任务不是异步和等待模式。尽管它们有共同的任务,但它们不是同一回事。
最后,是,如果您发现需要急于使用异步代码而忘记使用方式,请仔细考虑如何处理所有错误。
以下是一些准则。
async
Task.Run
,请不要调用await
或Result
或使用Wait