在数据访问层中使用异步时是否有任何性能提升?

时间:2014-10-06 10:33:07

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

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

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);
    }      
}

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

1 个答案:

答案 0 :(得分:10)

考虑一下。

你打电话给某人并要求他们为你做点什么。当他们这样做的时候,你就等着他们等着他们说'#34;它已经完成了#34;。这是同步工作。打电话给他们的行为&#34;阻止&#34;直到他们完成了这份工作,然后你就可以回到你正在做的事情,之后

替代的,异步的方式,是你打电话,但不是在电话上等你挂断,而是在他们工作时做其他事情。一旦他们给你回电话,说'#34;它已经完成了&#34;,你会回去做你需要他们的结果。

现在,如果您在等待时无所事事,那么绝对没有性能提升,而恰恰相反。让对方给你回电的开销将增加到要完成的工作总量。

因此,通过上面对异步工作的描述,在等待数据访问层完成其工作时,您是否有任何代码可以做的事情?

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

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


现在,说了这么多,我阅读了我的回答下面的评论,然后我仔细阅读了你的代码,我相信你并没有真正利用正确的异步代码。

最好的方法是使用某种正确进行异步I / O的系统或代码。你的代码调用了Task.Run,这实际上只是在手机前面掠夺另一个人,等着你。

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

现在,如果您拨打第一个,在使用Task.Run创建的主题上,您实际上仍在阻止,您只是要求其他人为您执行此操作。

然而,第二个是我上面所描述的。

因此,在您的特定情况下,我会尽量避免使用Task.Run。现在,根据服务器的负载,可能有利于这样做,但如果可以,我会切换到使用底层对象的异步方法来正确执行它。