我正在做一些研究,以更好地理解C#的异步/等待。
我找到了一个网站,其中包含以下代码,以显示与async / await相比,同步处理速度有多慢:
public IActionResult Index()
{
Stopwatch watch = new Stopwatch();
watch.Start();
ContentManagement service = new ContentManagement();
var content = service.GetContent();
var count = service.GetCount();
var name = service.GetName();
watch.Stop();
ViewBag.WatchMilliseconds = watch.ElapsedMilliseconds;
return View();
}
[HttpGet]
public async Task<ActionResult> IndexAsync()
{
Stopwatch watch = new Stopwatch();
watch.Start();
ContentManagement service = new ContentManagement();
var contentTask = service.GetContentAsync();
var countTask = service.GetCountAsync();
var nameTask = service.GetNameAsync();
var content = await contentTask;
var count = await countTask;
var name = await nameTask;
watch.Stop();
ViewBag.WatchMilliseconds = watch.ElapsedMilliseconds;
return View("Index");
}
public class ContentManagement
{
public string GetContent()
{
Thread.Sleep(2000);
return "content";
}
public int GetCount()
{
Thread.Sleep(5000);
return 4;
}
public string GetName()
{
Thread.Sleep(3000);
return "Matthew";
}
public async Task<string> GetContentAsync()
{
await Task.Delay(2000);
return "content";
}
public async Task<int> GetCountAsync()
{
await Task.Delay(5000);
return 4;
}
public async Task<string> GetNameAsync()
{
await Task.Delay(3000);
return "Matthew";
}
}
我理解上述代码的高级别以及为什么它的执行速度更快。
我不明白的是,如果没有使用线程,那么处理是如何同时运行的?
我已经在几个地方读过,async / await不会创建新的线程来进行处理。那么,什么是async / await做什么来允许同时进行处理?三个await Task.Delay是并行运行的,对吗?如果它没有创建3个线程,它在做什么?
我只是想了解高层发生了什么。
让我知道。
提前致谢。
答案 0 :(得分:4)
如果没有使用线程,处理如何同时运行?
线程允许您在同一系统上并行计算。当涉及通信或其他I / O时,代码与之通信的系统不同。当您启动任务时,另一个系统开始工作。这与您的系统并行发生,在您await
任务之前,系统可以自由地执行任何其他操作。
三个
await Task.Delay
并行运行,对不对?
他们并非正在运行,他们并行地睡觉。睡觉需要很少的资源。这就是为什么它们似乎并行“运行”。
答案 1 :(得分:1)
我不明白的是,如果没有使用线程,那么处理是如何同时运行的呢?
您可以将其视为操作完成时触发的事件,而不是在操作完成之前阻塞线程。
我已经在几个地方读过,async / await不会创建新线程来进行处理。
async
和await
没有;那是真实的。有关async
和await
的工作原理的更多信息,请see my intro post。
那么,async / await做什么来允许同时进行处理?
async
/ await
的一个主要用例是基于I / O的代码。我有一篇很长的博客文章,详细介绍how asynchronous I/O does not require threads。
三个await Task.Delay是并行运行的,对吗?
我更喜欢使用术语“并发”,只是为了避免与Parallel
和并行LINQ混淆,这两者都是为CPU绑定的并行性创建的,并且不像async
那样通常工作。 / await
。所以,我会说并行和异步都是并发形式,这是异步并发的一个例子。
(也就是说,使用“平行”一词肯定与该术语的常用用法一致。)
如果它没有创建3个线程,它在做什么?
Task.Delay
不是基于I / O的操作,但它与一个非常类似。它使用下面的计时器,因此它与Thread.Sleep
完全不同。
Thread.Sleep
将阻塞一个线程 - 我相信它会一直到OS Sleep
调用,这会导致操作系统将线程置于等待状态,直到其睡眠时间到期为止。
Task.Delay
更像是I / O操作。因此,它设置一个计时器,在时间到期时触发事件。定时器由操作系统本身管理 - 随着时间的推移(CPU上的时钟周期),操作系统将在完成时通知定时器。它有点复杂(为了提高效率,.NET会合并管理的计时器),但这是一般的想法。
因此,重点是每个被阻止的Task.Delay
都没有专用线程。