2012-02-28 49 views
4

我有一個AsyncController和一個主頁,查詢用戶的朋友列表,並做一些數據庫工作。我爲調用外部Web服務的任何請求實現了異步操作方法模式。這是處理這種情況的有效方式嗎?在高請求量的時代,我看到IIS有時會陷入線程匱乏的狀態,我擔心我的嵌套異步魔法可能會以某種方式參與其中。ASP.NET MVC的AsyncController和IO綁定請求

我的主要問題/談話要點是:

  • 它是安全的窩一個異步控制器動作裏面一個IAsyncResult異步Web請求?或者這只是加倍負載的地方?
  • 使用ThreadPool.RegisterWaitForSingleObject處理長時間運行的Web請求的超時效率,還是會消耗ThreadPool線程並使應用程序的其餘部分無效?
  • 在Async Controller操作中執行同步Web請求會更高效嗎?

示例代碼:

public void IndexAsync() 
{ 
    AsyncManager.OutstandingOperations.Increment(); 

    User.GetFacebookFriends(friends => { 

     AsyncManager.Parameters["friends"] = friends; 

     AsyncManager.OutstandingOperations.Decrement(); 
    }); 
} 

public ActionResult IndexCompleted(List<Friend> friends) 
{ 
    return Json(friends); 
} 

User.GetFacebookFriends(Action<List<Friend>>)看起來像這樣:

void GetFacebookFriends(Action<List<Friend>> continueWith) { 

    var url = new Uri(string.Format("https://graph.facebook.com/etc etc"); 

    HttpWebRequest wc = (HttpWebRequest)HttpWebRequest.Create(url); 

    wc.Method = "GET"; 

    var request = wc.BeginGetResponse(result => QueryResult(result, continueWith), wc); 

    // Async requests ignore the HttpWebRequest's Timeout property, so we ask the ThreadPool to register a Wait callback to time out the request if needed 
    ThreadPool.RegisterWaitForSingleObject(request.AsyncWaitHandle, QueryTimeout, wc, TimeSpan.FromSeconds(5), true); 
} 

只是的QueryTimeout中止請求,如果它需要長於5秒。

回答

1

您首先描述的完全異步方法是最好的,因爲這會將TP線程釋放回池以供重用。您在其他地方執行其他阻止操作的可能性很大。 QueryResponse會發生什麼?儘管您異步獲取響應,您是否也異步讀取響應流?如果不是這樣,那麼應該減少TP飢餓。

+0

呵呵drat我正在使用StreamReader的ReadToEnd()讀取Stream,那就是它了。謝謝 :) – Foritus 2012-02-28 02:06:41