我試圖異步發出Web請求。我的代碼工作正常,除了一件事情:似乎沒有一種內置的方式來指定在BeginGetResponse
上的超時。 MSDN的例子清楚地表明工作的例子,但缺點是它們都結束了一個如何在不阻塞線程的情況下在HttpWebRequest.BeginGetResponse上指定超時值
SomeObject.WaitOne()
再次明確指出它阻止該線程。我將處於高負載環境,並且不能阻塞,但如果超過2秒,我還需要超時請求。沒有創建和管理單獨的線程池,是否有框架中可以幫助我的東西?
開始的例子:
- http://msdn.microsoft.com/en-us/library/ms227433(VS.100).aspx
- http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.begingetresponse.aspx
我想是在BeginGetResponse()
異步回調的方式來調用我的超時參數過期後,有一些跡象表明,發生超時。
看似明顯的TimeOut
參數在異步調用中不受尊重。 ReadWriteTimeout
參數在響應返回之前不起作用。 非專有解決方案將是更可取的。
編輯:
這就是我想出了:調用BeginGetResponse
後,我創建我的持續時間Timer
,這就是加工的「開始」階段的結束。現在要麼將完成請求,我的「結束」階段將被稱爲或超時期限將到期。
爲了檢測比賽並獲得單一勝利者,我呼籲以線程安全的方式增加一個「已完成」的計數器。如果「超時」是要返回的第一個事件,則中止請求並停止計時器。在這種情況下,當調用「結束」時,EndGetResponse
將引發錯誤。如果「結束」階段首先發生,它會增加計數器,「超時」會放棄請求。
這似乎像我想要的那樣工作,同時也提供可配置的超時。缺點是額外的計時器對象和我無法避免的回調。我看到1-3線程處理各個部分(開始,超時,結束),所以它看起來像這樣工作。我沒有任何「等待」電話。
我是否錯過了太多的睡眠或者是否找到了一種方法來處理我的請求而不會阻塞?
int completed = 0;
this.Request.BeginGetResponse(GotResponse, this.Request);
this.timer = new Timer(Timedout, this, TimeOutDuration, Timeout.Infinite);
private void Timedout(object state)
{
if (Interlocked.Increment(ref completed) == 1)
{
this.Request.Abort();
}
this.timer.Change(Timeout.Infinite, Timeout.Infinite);
this.timer.Dispose();
}
private void GotRecentSearches(IAsyncResult result)
{
Interlocked.Increment(ref completed);
}
你最終採取了什麼方法?這一個還是你找到了更好的方法?你有沒有得到完整的來源? – mythz 2011-01-13 02:07:04