2016-06-10 66 views
5

當IIS收到HTTP請求時,會將請求轉交給由一個或多個工作進程提供服務的應用程序池中請求的應用程序。一個工作進程會從共享線程池中產生一個線程(如果需要的話)來處理http請求。 (i)在web api控制器的上下文中,當接收到這個請求時,控制器是否實例化並分配給了產生的線程? (ii)當同一api控制器有多個http請求時,每個衍生線程的控制器是否會有多少個實例? (iii)在非線程安全的資源(dbContext)在類級別聲明並在構造函數中實例化,然後在類方法中使用的場景中。會否存在提交和管理交易的問題?Web Api控制器和線程池

從本質上講,每個線程是否存在控制器實例的一對一匹配? (我知道,使用asp.net,多個線程實際上可以服務一個http請求)。

回答

3

(ⅰ)在web API控制器的上下文中,當該請求被接收 ,在控制器實例化,並分配給所述派生 線程? (ii)當有多個http請求到同一個api控制器時, 會有多少個控制器的實例在每個產生的線程中?

當收到請求時,控制器實例由ControllerFactory或DependencyResolver創建。

基本上,主線程創建一個控制器實例,然後在多個線程之間共享相同的實例,直到請求完成。

(III)在非線程安全的 (的DbContext)的資源在類級別聲明,並在 構造函數實例,然後在類方法中使用的情況。是否有問題 提交和管理交易?

是的,共享成員或靜態不是線程安全的。但是,操作方法內的局部變量是線程安全的。

+0

因此,有必要在動作方法中實例化一個dbcontext,並在動作方法的作用域內重用它們與不同存儲庫的多個實例。我已經試過這個,它的作品:)。但我擔心任何代碼味道... –

1

回答您的問題的點:
(i)。 (ii)是
。不。通常控制器是單身的,不是線程安全的。您創建多個線程來處理多個請求,但它們調用相同的控制器實例(或服務)
(iii)。是。您有責任關注數據完整性檢查或線程安全問題。如果你不這樣做,那麼你可以面對各種問題,如髒讀,骯髒的騎行,線程安全......所有類型的線程安全問題。

您可以將控制器視爲服務,只需通過創建新實例(例如爲每個請求創建新任務處理程序)將傳入請求委託給新的子服務或控制器,但仍然需要考慮共享資源(如數據庫)的線程安全性。

+0

你確定你對(ii)的回答嗎? 本頁內容 https://docs.microsoft.com/zh-cn/docs.microsoft。com/en-us/aspnet/web-api/overview/advanced/dependency-injection 它聲明: 「控制器是根據請求創建的。」 但也許我誤解你 – schmendrick