2014-10-06 28 views
1

我有一個疑問,是否有任何性能增益,如果我使用異步功能在如下數據訪問層:在數據訪問層中使用異步時是否有任何性能增益?

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

此外,如果不是當它更有意義?

+0

單個請求永遠不會更快,優點是它不會阻止。 – 2014-10-06 10:37:38

+0

取決於如何衡量性能。對於使用ASP.Net服務器的單個用戶來說,性能會下降。爲了服務1M命中/秒,你會發現好處(假設你避免了'Task.Run',並且只是I/O的異步)。 – Aron 2014-10-06 10:37:46

回答

8

請考慮這一點。

你打電話給某人,讓他們爲你做點事情。當他們這樣做的時候,你等待着,等待他們說「完成了」。這是同步工作。在他們完成這項工作之前將他們稱爲「塊」的行爲,然後你可以回到你正在做的任何事情上,之後

另一種異步方式是讓你打電話,但不要等待電話掛斷,而是在工作時做其他事情。一旦他們給你回電話,說「完成了」,你就回去做你需要的結果。

現在,如果你無事可做當你等待時,絕對沒有任何性能增益,反而恰恰相反。讓另一方回電給你的開銷將增加到工作總量中。

因此,通過上面對異步工作的描述,您是否有任何代碼可以在等待數據訪問層完成其工作時執行任何操作?

如果不是,那麼不,沒有性能增益。

如果是,那麼可能會有性能提升。現在


,說了這麼多,我看了我的回答如下的評論,然後我多一點仔細重讀你的代碼,我相信,你是不是真正得到了正確的異步代碼的優勢在這裏。

最好的方法是使用某種系統或代碼來正確執行異步I/O。你的代碼調用Task.Run,這實際上就像將一個不同的人放在電話前一樣,等待着你。

例如,考慮SqlCommand,這可能是實際的代碼做了交談,這裏的數據庫,它有兩個有趣的方法:

現在,如果你打電話給第一個,在Task.Run創建的線程上,你實際上仍然阻塞,你只是要求別人爲你做。

然而,第二,正如我上面所述。

因此,在您的具體情況下,我會盡量避免使用Task.Run。現在,根據服務器的負載情況,可能是有利於做到這一點,但如果可以,我會切換到使用底層對象的異步方法來正確執行它。

+3

在這種特殊情況下,還有一件事需要考慮。異步行爲通過'Task.Run'完成,相當於抓住最近的溫暖身體排隊等候。這是最差的一種異步,因爲你失去了一個溫暖的身體(一個線程),這可能會做一些其他有用的工作,並且增加了所有這些打電話的複雜性。 – Aron 2014-10-06 10:51:21

+0

好的,讓我在這裏寫一些更多的文字。 – 2014-10-06 10:52:21

+0

感謝您的回覆。其實我也是這麼想的。我只需要別人來確認。 – 2014-10-06 11:02:51

相關問題