2015-10-22 89 views
0

我正在建立一個網站使用asp.net mvc 5.asp.net mvc太多查詢一個頁面實體框架並行?

目前我使用依賴注入爲每個請求dbcontext注入我的控制器。

但EF不是線程安全的,因此一個dbcontext不能用於並行查詢。

是否值得對我的網站進行更改,以便本頁使用這樣的smt?

using(var ctx = new dbcontext) { 
    //creating a task query like tolistasync 
} 

using(var ctx2 = new dbcontext) { 
    //creating a task query like tolistasync 
} 

using(var ctx3 = new dbcontext) { 
    //creating a task query like tolistasync 
} 
. 
. 
. 
. 
. 
. 
. 
using(var ctx20 = new dbcontext) { 
    //creating a task query like tolistasync 
} 

然後:

Task.WhenAll(t1,t2,t3,......,t20) 

或者我應該只使用一個的DbContext每個請求,做財產以後這樣的:

var query1result = await query1.ToListAsync(); 
var query2result = await query2.ToListAsync(); 
var query3result = await query3.ToListAsync(); 
var query4result = await query4.ToListAsync(); 
. 
. 
. 
. 
. 
var query19Result = await query19.ToListAsync(); 
var query20Result = await query20.ToListAsync(); 

在第一種情況下就不會有這麼多的開啓和關閉連接到數據庫。

在第二會有一個連接,但一切都發生順序

這種情況下,最好的,爲什麼?

+0

如果你在'using'中封裝上下文,我不認爲它們中的任何一個都可以工作,因爲這將在異步任務完成之前關閉連接。 – DavidG

+0

我知道我只是爲了澄清問題 – 1AmirJalali

回答

1

但EF不是線程安全的,因此一個dbcontext不能用於並行查詢。

「線程安全性」與「支持多個併發操作」完全不同。

是否值得對我的網站進行更改,以便本頁使用smt這樣?

哪種情況更好?爲什麼?

只有你可以回答這個問題。

但是,有一些一般指導。

首先,針對數據庫的操作通常是I/O綁定的,而不是CPU綁定的。請注意,此規則有很多例外情況。其次,如果所有/大部分操作都碰到同一個數據庫,那麼在文件級別上會出現明確的爭用。第三,如果數據庫位於傳統(即非固態)硬盤驅動器上,則在磁盤盤片級別會出現更多爭用。

那麼,這一切是說,如果後端僅僅是一個普通的SQL Server,那麼你可能不會看到任何好處(即,更快的響應時間)從併發數據庫操作時,該服務器是在正常加載。事實上,在這種情況下,根本不會從異步數據庫調用中看到任何好處(與同步調用相比)。

但是,如果您的後端更現代化,比如Azure SQL實例(特別是SSD上運行的實例),那麼併發數據庫操作的確可以加快您的請求速度。

0

首先,問問自己 - 你真的有性能問題嗎?如果沒有 - 像往常一樣 - 在一個DbContext。這是最簡單和非常安全的方式。

如果你有問題?讓我們試試:

如果您的查詢是隻讀的,則可以並行運行多個線程。創建新的DbContext並打開新的連接 - 通常不是一個大問題。此外,您可以撥打AsNoTracking致電所有您的只讀查詢。因此,EF不會在上下文中緩存實體。

但是,請三思。調試並發現並行執行代碼中的問題更加困難。所以,你的操作必須非常簡單。

0

如果你真的要處理很多查詢,你可以並行運行它們。我會用Parallel.ForEach