async / await:如果它不使用线程它同时运行处理它做了什么?

时间:2017-06-03 23:47:54

标签: asynchronous async-await

我正在做一些研究,以更好地理解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个线程,它在做什么?

我只是想了解高层发生了什么。

让我知道。

提前致谢。

2 个答案:

答案 0 :(得分:4)

  

如果没有使用线程,处理如何同时运行?

线程允许您在同一系统上并行计算。当涉及通信或其他I / O时,代码与之通信的系统不同。当您启动任务时,另一个系统开始工作。这与您的系统并行发生,在您await任务之前,系统可以自由地执行任何其他操作。

  

三个await Task.Delay并行运行,对不对?

他们并非正在运行,他们并行地睡觉。睡觉需要很少的资源。这就是为什么它们似乎并行“运行”。

答案 1 :(得分:1)

  

我不明白的是,如果没有使用线程,那么处理是如何同时运行的呢?

您可以将其视为操作完成时触发的事件,而不是在操作完成之前阻塞线程。

  

我已经在几个地方读过,async / await不会创建新线程来进行处理。

asyncawait没有;那是真实的。有关asyncawait的工作原理的更多信息,请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都没有专用线程。