2016-07-26 177 views
0

比方說,我有以下ApiController在我的ASP.NET的WebAPI應用:的WebAPI控制器重用

class MyApiController : ApiController 
{ 
    private string str; 

    [HttpGet] 
    public string SetStr(string str) 
    { 
     this.str = str; 
     MaybeSleep(); // Some executions take longer, some don't. 
     return this.str; 
    } 
} 

(現實情況是比較複雜一點,但是這應該是最重要的事情)

這是在我的環境和某些其他環境中運行良好,即使在繁重的服務器負載下也總是返回輸入值。

但是,在兩種環境中,即使沒有太多的服務器負載,str 有時也會在設置和返回之間「奇蹟般」變化。但是,它總是會更改爲在那段時間發送到服務器的值,但並不總是在此請求中發送的值。

所以,我的問題是:

  • 是ApiController重用的行爲,我只是期望,或者出現新的ApiController創建,使用和銷燬的每一個請求的服務器進程?
  • 此行爲取決於ASP.NET版本,IIS版本和/或Web.config設置?
  • 是否存在有關Microsoft提供的私人ApiController變量行爲的文檔?
  • 或者這可能是某個.NET或ASP.NET版本中的已知錯誤?
+2

爲每個請求創建一個新的控制器,以便除非你有一個共享的資源干擾,這應該被隔離。 –

+1

我很肯定你的例子是錯誤的,並不能反映現實世界的情況。首先,我不認爲控制器可以以這種方式重用(如果他們可以的話,我會很擔心我的一些項目)。第二個重用或不是你只是返回參數。您將該字段用作一種局部變量。 – Stilgar

+0

除非您對多個調用使用相同的ApiController引用。 (就像創建一個全局控制器並調用方法一樣,它將重寫每個調用的屬性),你應該很好。正如Stilgar所說,這可能不是全部情況,並且可能還有更多的情況,那麼似乎 –

回答

1

的請求不應該修改控制器的狀態。從入口方法到任何其他被調用的方法,都可以根據需要傳遞參數,因此不需要根據請求修改控制器對象本身。

如果在整個請求過程中需要維護一些狀態,以至於無法將參數傳遞給其他方法,那麼最好的做法是在HttpContext上,因爲它始終是特定於請求的。 (即使那樣,這種情況可能並不常見。)

代替此:

public string SetStr(string str) 
{ 
    this.str = str; 
    MaybeSleep(); // Some executions take longer, some don't. 
    return this.str; 
} 

此:

public string SetStr(string str) 
{ 
    HttpContext.Items["str"] = str; //I'd declare a constant for "str" 
    MaybeSleep(); 
    return HttpContext.Items["str"]; 
} 
+0

你有鏈接來備份你的第一句話嗎?這似乎與另一個答案以及三條評論相矛盾。 – Alexander

+0

不,我不知道。我也完全不同意其他意見 - 我的回答是相輔相成的。沒有規定說控制器不能從請求中獲得某種狀態,但它違背了穀物。如果你的控制器是無狀態的,那麼你不必擔心它們是否被重用。 –

1

是ApiController重用的行爲,我只是期待,或 應新ApiController創建,使用和銷燬,每 單個請求的服務器進程?

當收到請求時,ControllerFactory或DependencyResolver會創建一個新的控制器實例。

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

由於第一個假設不正確,問題的其餘部分不再相關。

理想情況下,如果您執行長時間運行的進程,您希望使用調度程序,以便它不會凍結UI。

你可以閱讀更多斯科特Hanselman的博客 - How to run Background Tasks in ASP.NET