【问题标题】:Is there any performance gain when using async in Data Access Layer?在数据访问层中使用异步是否有任何性能提升?
【发布时间】:2014-11-30 14:31:29
【问题描述】:

我怀疑如果我在数据访问层中使用异步功能是否有任何性能提升,如下所示:

public async Task<IEnumerable<TrnApplicant>> GetAllMemberApplicantsAsync(String webReferenceNumber)
{
    using (var context = new OnlineDataContext())
    {
        var applicant = await Task.Run(() => context.Applicants.First(
                app => app.RefNo.Equals(webReferenceNumber, StringComparison.OrdinalIgnoreCase)) );

        return GetApplicantsInGroup(applicant.ApplicantsGroupId);
    }      
}

如果不是,什么时候更有意义?

【问题讨论】:

  • 单个请求永远不会更快,优点是它不会阻塞。
  • 取决于如何衡量性能。对于使用 ASP.Net 服务器的单个用户,性能会下降。对于服务 1M hit/s,您会发现好处(假设您避免 Task.Run 并且仅异步 I/O)。

标签: c# asp.net-mvc asp.net-mvc-4 asynchronous c#-5.0


【解决方案1】:

考虑一下。

您打电话给某人并要求他们为您做某事。当他们这样做时,您在线等待,等待他们说“完成了”。这是同步工作。在他们完成工作之前称他们为“障碍”的行为,然后你可以回到你正在做的任何事情,之后

另一种异步方式是让您拨打电话,但不是在电话上等待,而是挂断电话,并在他们工作时做其他事情。一旦他们给你回电话,说“完成了”,你就回去做任何你需要他们做的事情。

现在,如果你在等待的时候无事可做,绝对不会有任何性能提升,相反。让对方回电的开销反而会增加总工作量。

那么通过上面对异步工作的描述,你的代码在等待数据访问层完成它的工作时有什么可以做的吗?

如果不是,那么不,不会有性能提升。

如果是,那么可能会有性能提升。


现在,说了这么多,我阅读了我的答案下面的评论,然后我更仔细地重新阅读了您的代码,我相信您并没有真正利用这里适当的异步代码。

最好的方法是使用某种系统或代码来正确执行异步 I/O。您的代码调用Task.Run,实际上就像只是将另一个人放在电话前,等待您。

例如,考虑SqlCommand,这可能是这里与数据库对话的实际代码,它有两个有趣的方法:

现在,如果您在使用Task.Run 创建的线程上调用第一个,实际上您仍处于阻塞状态,您只是在请求其他人为您执行此操作。

然而,第二个就像我上面描述的那样。

所以在你的特殊情况下,我会尽量避免使用Task.Run。现在,根据您的服务器的负载,可能这样做是有利的,但如果可以的话,我会切换到使用底层对象的异步方法来正确地完成它。 p>

【讨论】:

  • 在这种特殊情况下,还有一件事需要考虑。异步行为是通过Task.Run 完成的,这相当于抓住最近的温暖身体为您排队等候。这是最糟糕的异步,因为你失去了一个温暖的身体(一个线程),它可能正在做一些其他有用的工作,并且你增加了所有这些电话的复杂性。
  • 感谢您的回复。其实我也是这么想的。我只是需要别人来确认。
  • 另外,如果后端可以比 ASP.NET 服务器扩展得更远,只有正确的 async 才有好处。
猜你喜欢
  • 2013-11-22
  • 2016-05-15
  • 2012-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-09
  • 2019-12-05
  • 2012-05-18
相关资源
最近更新 更多