msdn文档里提到的不会创建新线程是指async函数本身不会直接在新线程中运行。
在 MVC 模式下:
异步action执行到await之前都是再loop线程,loop线程池的线程数是有限的,在iis线程池的高级设置(queue length)里可以设置,一旦执行到await之后,就会开启另一个线程去执行await的任务,同时,loop线程回池去接收其他请求,当await执行完了又会从loop线程池拿一个线程处理接下来的任务。这样做的好处是不回阻塞loop线程,提高并发(并不是提高单个action的执行效率)。await的任务也最好是高io,低计算的任务(比如文件读写,网络请求,数据库读写)。这样比较划算
异步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
{
//创建一个秒表来获取执行时间
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;
});
}
{
var t = xxx();
var i = t.Result;
return View();
}
public async Task<int> xxx()
{
return await Task.Run(() =>
{
var i = 0;
i++;
return i;
});
}