2015-05-27 65 views
0

在我的ASP.NET MVC Web應用程序中,我正在使用一個有時可能需要很長時間才能響應的Web服務。在這種情況下,用戶可能想要取消請求並能夠提出其他請求。但是,由於服務器仍在忙於處理先前的請求,用戶必須等到該請求完成。出於這個原因,我決定做一些執行密集IO作業異步的操作方法,希望主線程不會被阻塞。但是這並沒有幫助。這是我的方法:請求可以在單獨的線程上處理嗎?

1:public class TestController:AsyncController{ 
2: public async Task<ActionResult> GetString(){ 
3: 
4:  string data=await Task<string>.Factory.StartNew(()=>{ 
5:   return service.GetDataAsString("name"); 
6:  }); 
7:  return View(data); 
8: } 
9:} 

第7行將不會執行,除非服務返回期望的字符串,所以仍然阻塞仍然存在。我需要做什麼才能使整個行動在單獨的線程中進行?我必須走舊時尚嗎?這種事情不是異步方法嗎?

+1

可能是你看錯了方向。什麼可能會導致你的問題,會話鎖。嘗試禁用它,裝飾控制器的下一個屬性:[SessionState(SessionStateBehavior.Disabled)] – Uriil

+0

這顯然會禁用會議狀態,這不是我想要的。如果這是唯一的方法,那麼這意味着我必須犧牲兩者之一:會話或用戶體驗。我對麼? –

+1

@MikeJM - 我想你以後是火與忘記。或者,您可以將您的操作分爲兩個操作(一個返回視圖,另一個執行服務調用)並從客戶端執行兩個單獨的請求。 – heymega

回答

2

這是不是異步方法的意思嗎?

不,async不會更改HTTP協議。您每個請求仍然只有一個響應,並且該響應只能發送一次。

async騰出調用線程,但在ASP.NET這只是意味着該線程返回線程池,並能處理其他請求;它不會向用戶發送HTTP響應。在你的特定情況下,代碼首先從線程池(StartNew)獲取一個線程,以釋放線程池中的線程(await),這是毫無意義的。

有幾個解決方案應該工作。您可以刪除會話狀態或將此呼叫替換爲SignalR集線器(允許其他用戶請求在舊節點完成時),也可以使用AJAX樣式 - 最好使用reliable queue connected to an independent worker process

相關問題