我可能沒想到正確的方向。我是Dependency Injection和ASP.Net Core的新手。

我有一個ASP.Net核心網站,其中一個任務是將數據從Excel工作表導入用戶將上傳的數據庫。 excel表格可能很大,數據轉換任務需要時間,因此我希望在後台執行它們。即用戶將上傳工作表,響應將立即發送,後台作業/線程將導入數據。

我試圖通過以下方式運行後台工作:

Task.Run(() => ProcessImport(model));

我遇到的問題是Process導入方法調用具有存儲庫類的服務,該存儲庫類通過作為Scoped添加的ASP.Net依賴注入容器訪問AppDbContext,並且一旦響應被發回,則處理上下文。我得到一個運行時異常,你不能在它被處置後使用上下文。

我的問題是,處理這種情況的最佳方法是什麼?我應該製作AppDbContext單例嗎?我應該在ProcessImport方法中創建一個新的AppDbContext實例,並將其傳遞給它嗎?我讀過DbContext不是線程安全的,所以這是一個好方法嗎?

一般承認的答案

您應該將IServiceScopeFactory實例(它的單例)傳遞給您的任務。

在內部任務中,當數據到達時,您應該創建新的CreateScope()並從該範圍請求服務。當數據處理完成時 - 處置此範圍(但是對下一次運行保持對IServiceScopeFactory引用)。

例如,見這個 。我用這個庫運行小而快的任務。

對於重型/長期運行的任務,正如Gert所寫,不要依賴於您的任務將始終運行完成。準備好重新啟動,準備好重新處理相同的數據。


熱門答案

要分解您的問題:

  1. 處理這種情況的最佳方法是什麼?

    API處理長時間運行的任務並不理想。您可以將該過程委派給後台應用程序

  2. 我應該製作AppDbContext單例嗎?

    dbContext在Web應用程序方案中不應該是單例,因為它可能會導致管理事務等問題。

  3. 處理這種情況的最佳方法是什麼?

    細分各種服務/流程:

    • 將採用文件的API。理想情況下,API應該只將文件作為輸入並將其保存到磁盤或數據庫。
    • 將處理文件的服務。將此組件/服務創建為單獨的庫。然後從控制台應用程序中使用此庫。這樣您就可以分析性能。通過使其成為異步方法使其成為火併忘記方法。這樣您就可以靈活地重用代碼。
    • 如果您不希望大量文件上傳,則可以在API控制器上重用該庫,並使用QueueBackgroundWorkItem執行該方法。請參閱此處以供參考: http//www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx
  4. 我應該在ProcessImport方法中創建一個新的AppDbContext實例,並將其傳遞給它嗎?

    由於它不是線程安全的,因此在每個線程中創建並使用dbContext類的單獨實例。

  5. 我讀過DbContext不是線程安全的,所以這是一個好方法嗎?

    有關使用EF dbContext的深入指南,請查看此博客: http ://mehdi.me/ambient-dbcontext-in-ef6/



Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow