【问题标题】:Doubts about async web api 2 operation关于 async web api 2 操作的疑问
【发布时间】:2017-05-11 10:52:36
【问题描述】:

在一些关于异步 Web api 2 操作的文章中,我发现了以下代码,展示了如何在 Web Api 2 中实现异步操作:

 public class UserController : ApiController
        {
            ApiSecurityEntities _db = new ApiSecurityEntities();

            public async Task<IHttpActionResult> Delete(Int32 Id)
            {
                 var record = await _db.UserMaster.Where(f => f.id == Id).FirstOrDefaultAsync();
                 if (record != null)
                 {
                     _db.UserMaster.Remove(record);
                     await _db.SaveChangesAsync();
                     return Ok();
                 }
                 return NotFound();
            }
        }

我想这段代码不是异步的,但它只用async/await 字包裹。你能打消我的疑虑吗?

#EDIT

我认为这不是真正的异步代码的原因:

  • 在第一个await之后只有if语句必须等待上一个操作,并且在这个块之后不会做任何其他工作,所以它会同步运行
  • 第二个await之后有return语句,所以必须等到_db.SaveChangesAsync();完成

【问题讨论】:

  • 为什么不应该是异步的?
  • 拥有await 关键字将允许框架在等待数据库返回数据时执行其他工作..
  • “我想这段代码不是异步的”——你能澄清一下为什么你认为这段代码不是异步的吗?您在这里有两个异步数据库操作
  • @mkul 不。整台计算机可以做其他事情,而不仅仅是你的代码。这也是一个 Web API 控制器,所以可以有多个用户/线程..
  • 我相信您可能将异步与多线程混淆了。

标签: c# asp.net asynchronous


【解决方案1】:

这段代码在 I/O 方面绝对是真正的异步。

在计算机科学中,异步 I/O 或“非顺序 I/O”是一种 允许其他处理的输入/输出处理形式 在传输完成之前继续。

来自wikipedia

在您的情况下,您的方法在等待 I/O 完成(数据库操作)时不会阻塞任何线程,使用 await 您告诉当前线程它可以返回到 ThreadPool 并做任何其他工作在 I/O 操作完成之前。

任何线程(某种处理单元)在数据库按照异步定义执行其工作时都不会被阻塞。

#EDIT

正如你所说,你的代码执行顺序没有改变,它需要来自数据库的结果来执行下一个语句,但是(!)虽然这段代码似乎阻塞(又名同步)它 will not block any thread 而我/O 操作正在执行。
await 关键字允许您以异步方式“等待”结果,当 I/O 完成后,它将继续执行该方法的其余部分。

【讨论】:

  • 所以最好把所有的数据库操作都放在async/await中,即使代码看起来会同步运行操作?
  • 没错,通过这样做,您可以更有效地使用您的资源(线程),而不是让您的线程无缘无故地等待外部操作,它们可以做其他工作,例如回答其他请求,这个原则确实可以帮助服务器的可扩展性。
  • @mkul 您似乎反复错过了异步/等待的要点。它与多线程或并行执行代码无关。另请注意,在 ASP.NET 的特定情况下,使用异步的好处是 scalability rather than performance
猜你喜欢
  • 2014-10-05
  • 2016-12-02
  • 2011-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-10
相关资源
最近更新 更多