2014-03-26 60 views
0

我試圖加快我的一些代碼,並行任務的代碼,使多個數據庫訪問

我做2或3讀取一個緩慢的數據庫,我想打這些電話中paralle運行。

FSKWebInterfaceEntities dbSrc = new FSKWebInterfaceEntities(); 

public void main() 
{  
var TaskUsr = GetUserAsync(dev); 
var TaskOldCompany = GetOldCompanyAsync(dev); 
await Task.WhenAll(); 

var usr = TaskUsr.Result; 
var oldCompanyName = TaskOldCompany.Result; 
..... 
use my two variables to insert a new entry into my localdb 
} 


    private async Task<ut_User> GetUserAsync(ut_UserAPNdevices dev) 
    { 
     return dbSrc.ut_User.FirstOrDefault(x => x.UserID == dev.UserID); 
    } 

    private async Task<String> GetOldCompanyAsync(ut_UserAPNdevices dev) 
    { 
     return dbSrc.ut_User.FirstOrDefault(x => x.UserID == dev.UserID).Company; 
    } 

在我的兩個輔助方法中,它的下劃線是綠色的,並表示沒有等待,因此會同步運行。但我不能返回return await dbSrc.ut_User.FirstOrDefault(x => x.UserID == dev.UserID);

我該如何修改我的代碼,使兩個讀取並行?

+1

什麼是dbSrc?該線程是否安全,並且可以處理2個線程(提示:大多數數據庫組件不是)。 – TomTom

+0

對不起,我忘了寫這個。那麼這是一個EF dbContext – Zapnologica

+0

不可能。對於每個正在運行的操作,您都需要單獨的dbContext - 它們不是線程安全的。 – TomTom

回答

0

您可以等待該行,因爲它不是異步方法。你不能真正等待數據庫調用,因爲它們不是線程安全的。請參閱this線程以獲取此方法的示例,以及有關爲什麼不這樣做的更好解釋。您可以考慮使用具有async methods的SqlCommands。

+0

您可以參考LINQ to SQL,它不是實體框架。 – Noseratio

0

您不能同時使用相同的EF DbContext。從EF團隊的statement about thread safety

目前,EF會如果開發商試圖在同一時間執行 2異步操作,並拋出檢測。

您仍然可以異步調用它們,而是順序:

public async Task main() 
{  
var sr = await GetUserAsync(dev); 
var oldCompany = await GetOldCompanyAsync(dev); 
..... 
use my two variables to insert a new entry into my localdb 
} 

更新解決註釋:

莫非你可能後我將如何改變一個簡單的例子,我的 上面的代碼使用多個dbcontext,因爲我不知道 正確的方式來做到這一點,我會在黑暗中編碼。

像下面這樣的東西。我不是EF的專家,向你保證這實際上會縮短處理時間。爲每個上下文打開數據庫連接可能會有相當大的開銷。

public async Task main() 
{  
var TaskUsr = GetUserAsync(dev); 
var TaskOldCompany = GetOldCompanyAsync(dev); 
await Task.WhenAll(TaskUsr, TaskOldCompany); 

var usr = TaskUsr.Result; 
var oldCompanyName = TaskOldCompany.Result; 
..... 
use my two variables to insert a new entry into my localdb 
} 

private async Task<ut_User> GetUserAsync(ut_UserAPNdevices dev) 
{ 
using (var dbSrc = new FSKWebInterfaceEntities()) 
    return dbSrc.ut_User.FirstOrDefault(x => x.UserID == dev.UserID); 
} 

private async Task<String> GetOldCompanyAsync(ut_UserAPNdevices dev) 
{ 
using (var dbSrc = new FSKWebInterfaceEntities()) 
    return dbSrc.ut_User.FirstOrDefault(x => x.UserID == dev.UserID).Company; 
} 
+0

所以我可以做到這一點,但它實際上不會幫助我加快程序,因爲它仍然按順序運行? – Zapnologica

+0

@ Zapnologica正確,所以如果你想要多次調用,你需要多個DbContext實例,也許在函數內部創建一個新的上下文,而不是全局共享一個(確保你使用'using'塊來處置它) –

+0

@ Zapnologica,正確的,它只會幫助你的代碼更好地擴展,如果它是Web應用程序或WCF服務。要並行運行它,請按照@TomTom和Scott Chamberlain的建議,爲每個任務使用單獨的'DbContext'對象。 – Noseratio