为什么要避免同步读取
ASP.NET Core 中的全部 I/O 操纵都是异步的。服务器实现了 Stream 接口,该接口同时具备同步和异步的方法。
在举行 I/O 操纵时,应优先使用异步方法,以避免阻塞线程池的线程。
假如阻塞了线程池线程,可能会导致服务器无法处理更多哀求,造成急剧性性能下降。
尤其是当客户端上传速率缓慢时,同步读取将阻塞线程直到整个哀求体被全部读取完成。
如何避免同步读取
错误的做法
以下代码示例使用了同步方法 ReadToEnd,导致线程被阻塞:- public class BadStreamReaderController : Controller
- {
- [HttpGet("/contoso")]
- public ActionResult<ContosoData> Get()
- {
- var json = new StreamReader(Request.Body).ReadToEnd();
- return JsonSerializer.Deserialize<ContosoData>(json);
- }
- }
复制代码 在这段代码中,Get方法将整个 HTTP 哀求体同步读入内存。假如客户端上传速率缓慢,应用步伐将阻塞在这个读取操纵上,导致服从下降。
正确的做法
使用异步方法 ReadToEndAsync,可以避免阻塞线程:- public class GoodStreamReaderController : Controller
- {
- [HttpGet("/contoso")]
- public async Task<ActionResult<ContosoData>> Get()
- {
- var json = await new StreamReader(Request.Body).ReadToEndAsync();
- return JsonSerializer.Deserialize<ContosoData>(json);
- }
- }
复制代码 这段代码使用异步读取方法,在读取过程中不会阻塞线程,可以提升性能和响应速率。
读取表单数据时的注意事项
错误的做法
使用 HttpContext.Request.Form,会在内部执行同步读取,导致线程被阻塞:- public class BadReadController : Controller
- {
- [HttpPost("/form-body")]
- public IActionResult Post()
- {
- var form = HttpContext.Request.Form;
- Process(form["id"], form["name"]);
- return Accepted();
- }
- }
复制代码 正确的做法
使用 ReadFormAsync,举行异步读取:- public class GoodReadController : Controller
- {
- [HttpPost("/form-body")]
- public async Task<IActionResult> Post()
- {
- var form = await HttpContext.Request.ReadFormAsync();
- Process(form["id"], form["name"]);
- return Accepted();
- }
- }
复制代码 这种做法使用异步方式读取表单数据,能有用避免阻塞线程池资源。
结论
在 ASP.NET Core 开辟中,应符合框架的异步操纵模式,避免使用同步方法读取 HTTP 哀求文本。
如许可以有用地提升应用步伐的性能和响应速率,避免因阻塞导致的急剧性性能下降。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |