gpt4 book ai didi

c# - 异步任务 获取 VS HttpResponseMessage 获取

转载 作者:行者123 更新时间:2023-12-02 07:20:15 28 4
gpt4 key购买 nike

我需要您在以下方面提供帮助。近一个月来,我一直在阅读有关任务和异步的内容。

我想尝试在一个简单的 wep api 项目中实现我新获得的知识。我有以下方法,并且它们都按预期工作:

 public HttpResponseMessage Get()
{
var data = _userServices.GetUsers();
return Request.CreateResponse(HttpStatusCode.OK, data);
}

public async Task<HttpResponseMessage> Get()
{
var data = _userServices.GetUsers();


return await Task<HttpResponseMessage>.Factory.StartNew(() =>
{
return Request.CreateResponse(HttpStatusCode.OK, data);
});
}

所以问题来了。我尝试使用 fiddler 看看这两者有什么区别。异步的速度要快一些,但除此之外,在 Web api 中实现类似的东西的真正好处是什么?

最佳答案

正如其他人所指出的,ASP.NET 上的async 的要点在于它释放了 ASP.NET 线程池线程之一。这对于自然异步操作(例如 I/O 绑定(bind)操作)非常有用,因为服务器上少了一个线程(没有线程“处理”异步操作 as I explain on my blog )。因此,服务器端异步的主要好处是可扩展性

但是,您希望避免在 ASP.NET 上使用 Task.Run(更糟糕的是 Task.Factory.StartNew)。我称其为“假异步”,因为它们只是在线程池线程上执行同步/阻塞工作。它们在您希望将工作从 UI 线程中推送出去以便 UI 保持响应的 UI 应用程序中很有用,但它们(几乎)永远不应该在 ASP.NET 或其他服务器应用程序上使用。

在 ASP.NET 上使用 Task.RunTask.Factory.StartNew 实际上会降低可伸缩性。它们会导致一些不必要的线程切换。对于运行时间较长的操作,您最终可能会放弃 ASP.NET 线程池启发式方法,导致创建额外的线程,然后又不必要地销毁这些线程。我一步步探索这些性能问题in another blog post .

因此,您需要考虑每个操作正在做什么,以及其中任何操作是否应该是异步的。如果应该,那么该操作应该是异步的。对于您的情况:

public HttpResponseMessage Get()
{
var data = _userServices.GetUsers();
return Request.CreateResponse(HttpStatusCode.OK, data);
}

Request.CreateResponse 到底在做什么?它只是创建响应对象。就是这样 - 只是一个奇特的。那里没有发生任何 I/O,而且它当然不需要被推送到后台线程。

但是,GetUsers 更有趣。这听起来更像是基于 I/O 的数据读取。如果您的后端可以扩展(例如,Azure SQL/表/等),那么您应该首先考虑使该异步,一旦您的服务公开了 GetUsersAsync,那么此操作也可以变为异步:

public async Task<HttpResponseMessage> Get()
{
var data = await _userServices.GetUsersAsync();
return Request.CreateResponse(HttpStatusCode.OK, data);
}

关于c# - 异步任务 <HttpResponseMessage> 获取 VS HttpResponseMessage 获取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25902275/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com