当前位置: 首页 > 知识库问答 >
问题:

.NET(dotnet)核心webapi和异步方法-需要反馈

戈建白
2023-03-14

我正在为PoC点构建我的dotnet core webapi服务,我关心的是为其他ARCH/Devs提供适当的指导。

“相同”方法签名的变化很少

  1. 公共动态获取(字符串名称=_defaultName)
  2. 公共IActionResult Get(字符串名称=_DefaultName)
  3. 获取公共异步任务(字符串名称=_defaultName)

撇开我为什么使用动态类型而不是自定义类型的讨论不谈,我试图理解它们的区别和好处。

    null
public async Task<IActionResult> Get(string name = _defaultName)
    {
        return await Task.Run(() => {
            dynamic response = new System.Dynamic.ExpandoObject();
            response.message = $"Hello {name}!";
            response.timestamp = DateTime.Now.ToUniversalTime();

            if (name.Equals(_defaultName, StringComparison.CurrentCultureIgnoreCase)) {
                response.hint = "Add forward slash and your name to the url, e.g.: hostname:port/my name";
            }

            return Ok(response);
        });
    }

我想知道,如果没有这种下游异步依赖关系,那么追求异步webapi方法和由此产生的看起来有点奇怪的代码是否有意义。

共有1个答案

乌灿
2023-03-14
  1. 无法控制http响应、头、代码等-所有这些都由框架设置。如果成功或失败,返回类型对运行时工具是可见的

您不应该永远使用动态,如果您需要从一个操作返回任意响应,您可以使用

public IActionResult Get(string name = _defaultName)
{
    // or any other method which accepts a response object)
    return Ok(someModel);
}

请求线程将在操作“是”的持续时间内保持不变。但如果您不使用任何异步操作(数据库访问、到另一个网站/WebService的网络连接或对数据库的读/写文件),使用它也是可以的。

// Here no async operations are called, so Task is not necessary
public IActionResult Index(string name = _defaultName)
{
    if(!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    return Ok();
}

这种假设是错误的。单独使用Task与真正的异步操作(I/O操作,如读取文件html" target="_blank">系统、网络连接或访问数据库)不会产生新线程。操作将启动,线程将返回到线程池。

则不会启动任何新线程。当异步操作完成时,将从线程池中取出一个线程并继续操作。

// No extra thread is called and the request thread is only 
// used in between "await" calls
public async Task<IActionResult> Get(string name = _defaultName)
{
    var result = await GetResultFromDatabase();

    return Ok(someModel);
}

请阅读Stephen Cleary关于MSDN的Async Programming:Async/Await on ASP.NET文章。它是关于ASP.NET MVC5(旧的webstack,而不是重写的ASP.NET核心)的,但该原则仍然适用于ASP.NET核心。

public IActionResult Get(string name = _defaultName)
{
    // Don't await or run CPU intensive stuff via Task.Run
    var result = SomeCpuIntensiveOperation();

    return Ok(result);
}

您还可以混合CPU绑定操作和异步操作

public async Task<IActionResult> Get(string name = _defaultName)
{
    // runs async, no extra thread
    var valueFromDb = await GetValueFromDb();

    // Don't await or run CPU intensive stuff via Task.Run
    // runs sync, on request thread
    var result = SomeCpuIntensiveOperation(valueFromDb);

    return Ok(result);
}

我想知道,如果没有这种下游异步依赖关系,那么追求异步webapi方法和由此产生的看起来有点奇怪的代码是否有意义。

这是由你来决定的,基于你的第三个假设的新知识

 类似资料:
  • 我一直使用关键字编写Web Api控制器方法,并且一直使用。我最近尝试了一个方法同步,以了解它将如何影响性能,但震惊地发现它对任何其他http请求都没有阻塞影响。 举个例子-- 这样,我就可以运行=>,然后运行任意数量的=>,并且不会阻塞对endpoint的请求。 我最初认为需要将Hello方法变为异步,这样对Goodbyeendpoint的请求就可以毫无延迟地返回。但是使此方法同步/异步没有任何

  • 我已经创建了非核心webapi项目来与移动应用程序交互。例如,如果我创建了一个名为Data的控制器,它有一个名为Search的方法,如下图所示。该项目已配置为发送和接收json数据。 我可以通过使用以下url,使用postman向该方法发送post请求http://localhost/api/Data/search 类似地,我可以在控制器内创建其他函数,并使用路由“/api/[controller

  • 我正在尝试从页面: 控制器: 但是我似乎无法在前端检索会话

  • 从sln目录工程 从解决方案目录工作 我不希望VS 2017必须安装在构建机器上,所以我从 https://www.visualstudio.com/downloads/ 安装了“Visual Studio 2017的构建工具”。 轰炸sln中的每个项目,错误如下: 错误 MSB4019:找不到导入的项目“C:\Program Files (x86)\Microsoft Visual Studio

  • .NET核心和ASP.NET核心到底有什么区别?

  • 我有一个.NET core项目,并且正在尝试使用授权选项创建自定义策略,如此处的文档所示: ASP.NET.Core授权-需求处理程序中的依赖注入 这些示例显示了使用 1 个参数(一个简单的 int 值)设置授权要求。我的自定义要求需要一个字符串参数以及一个 DbContext 对象。我想在运行时将 DbContext 注入到需求的构造函数中。我正在使用 Autofac 容器。我不确定如何实现这一