C# 正确理解 async 与 await

msdn文档里提到的不会创建新线程是指async函数本身不会直接在新线程中运行。
在 MVC 模式下:
异步action执行到await之前都是再loop线程,loop线程池的线程数是有限的,在iis线程池的高级设置(queue length)里可以设置,一旦执行到await之后,就会开启另一个线程去执行await的任务,同时,loop线程回池去接收其他请求,当await执行完了又会从loop线程池拿一个线程处理接下来的任务。这样做的好处是不回阻塞loop线程,提高并发(并不是提高单个action的执行效率)。await的任务也最好是高io,低计算的任务(比如文件读写,网络请求,数据库读写)。这样比较划算



public ActionResult GetList()
        {
            //创建一个秒表来获取执行时间
            var watch = new Stopwatch();
            watch.Start();


            var country = GetCountry();
            var state = GetState();
            var city = GetCity();


            watch.Stop();
            ViewBag.WatchMilliseconds = watch.ElapsedMilliseconds;


            return View();
        }


        public async Task<ActionResult> GetListAsync()
        {
            //创建一个秒表来获取执行时间
            var watch = new Stopwatch();
            watch.Start();


            var country = GetCountryAsync();
            var state = GetStateAsync();
            var city = GetCityAsync();


            Thread.Sleep(1000);
            
            var content = await country;
            var count = await state;
            var name = await city;


            //这种写法 和同步没有区别
            //var content = await GetCountryAsync();
            //var count = await GetStateAsync();
            //var name = await GetCityAsync();


            watch.Stop();
            ViewBag.WatchMilliseconds = watch.ElapsedMilliseconds;


            return View();
        }


        #region GetCountry方法GetList && GetListAsync
        public string GetCountry()
        {
            Thread.Sleep(1000); //使用 - 当你想阻塞当前线程
            return "India";
        }


        public async Task<string> GetCountryAsync()
        {
            await Task.Delay(1000); //使用 - 当您想要逻辑延迟而不阻塞当前线程
            return "India";
        }
        #endregion


        #region GetState方法用于GetList && GetListAsync
        public string GetState()
        {
            Thread.Sleep(2000); //使用 - 当你想阻塞当前线程
            return "Gujarat";
        }


        public async Task<string> GetStateAsync()
        {
            await Task.Delay(2000); //使用 - 当您想要逻辑延迟而不阻塞当前线程
            return "Gujarat";
        }
        #endregion


        #region  GetCity方法GetList && GetListAsync
        public string GetCity()
        {
            Thread.Sleep(3000); //使用 - 当你想阻塞当前线程
            return "Junagadh";
        }


        public async Task<string> GetCityAsync()
        {
            await Task.Delay(3000); //使用 - 当您想要逻辑延迟而不阻塞当前线程
            return "Junagadh";
        }
        #endregion


此写法 会导致 程序 假死,无限等待
public ActionResult Index()
        {
            var t = xxx();
            var i = t.Result;


            return View();
        }
        public async Task<int> xxx()
        {
            return await Task.Run(() =>
            {
                var i = 0;
                i++;
                return i;
            });
        }

猜你喜欢

转载自blog.csdn.net/foreverhot1019/article/details/79105885