[英]Async/Await single thread/some threads
我需要一个关于正确使用await的规则。 在.net core c#7.2中运行此代码:
static class Program
{
static async Task<string> GetTaskAsync(int timeout)
{
Console.WriteLine("Task Thread: " + Thread.CurrentThread.ManagedThreadId);
await Task.Delay(timeout);
return timeout.ToString();
}
static async Task Main()
{
Console.WriteLine("Main Thread: " + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("Should be greater than 5000");
await Watch(NotParallel);
Console.WriteLine("Should be less than 5000");
await Watch(Parallel);
}
public static async Task Parallel()
{
var res1 = GetTaskAsync(2000);
var res2 = GetTaskAsync(3000);
Console.WriteLine("result: " + await res1 + await res2);
}
public static async Task NotParallel()
{
var res1 = await GetTaskAsync(2000);
var res2 = await GetTaskAsync(3000);
Console.WriteLine("result: " + res1 + res2);
}
private static async Task Watch(Func<Task> func) {
var sw = new Stopwatch();
sw.Start();
await func?.Invoke();
sw.Stop();
Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds);
Console.WriteLine("---------------");
}
}
你们都可以看到两种方法的行为是不同的。 在实践中很容易出错。 所以我需要一个“拇指规则”。
真人的更新请运行代码。 并解释为什么Parallel()比NonParallel()运行得更快。
在没有await
情况下调用GetTaskAsync
,你实际上得到一个Task,其中包含要执行的方法(即GetTaskAsync
)。但是当调用await GetTaskAsync
,执行将暂停,直到方法执行await GetTaskAsync
,然后你得到结果。
让我更清楚一点:
var task = GetTaskAsync(2000);
这里,task的类型为Task<string>
。
var result = await GetTaskAsync(2000);
这里的结果是string
类型。
因此,要解决您的第一次询问:何时等待您的任务实际上取决于您的执行流程。
现在,至于为什么Parallel()
更快,我建议你阅读这篇文章 (一切都很有趣,但对于你的具体例子,你可以跳转到Tasks返回“热门” )。
现在让我们分解一下:
await
关键字用于暂停代码,直到任务完成,但实际上并未启动它。
在您的示例中, NotParallel()
将花费更长时间,因为您的任务依次执行,一个接一个地执行。 正如文章所解释的:
这是由于正在等待内联任务。
Parallel()
然而......
这些任务现在并行运行。 这是因为所有[任务]在随后等待所有[任务]之前开始,因为它们返回热点。
我建议您阅读以下内容: 基于任务的异步模式(TAP)
此处的“ 任务状态”部分非常感兴趣,可以了解冷热任务的概念:
由公共任务构造函数创建的任务称为冷任务,因为它们以非调度的创建状态开始其生命周期,并且仅在这些实例上调用Start时进行调度。
所有其他任务在热状态下开始其生命周期,这意味着它们所代表的异步操作已经启动
我邀请您详细阅读有关async/await
和Tasks
。 除了上面提供的资源之外,还有一些资源:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.