C#中HttpWebRequest的GetRequestStream執行的效率太低,甚至偶爾死掉


原文鏈接:http://www.crifan.com/csharp_httpwebrequest_getrequeststream_dead_hang_low_efficiency/

【已解決】C#中HttpWebRequest的GetRequestStream執行的效率太低,甚至偶爾死掉

【問題】

C#中,提交對應的POST類型http請求之前,會執行:

Stream postDataStream = req.GetRequestStream();

然后填充對應的post數據,再提交http的請求。

但是調試的時候,發現每次執行GetRequestStream都很慢。

慢也就算了,結果最近發現,某次,執行req.GetRequestStream();死掉。

【解決過程】

1.網上找了找,根據 GetRequestStream的效率為什么這么低? 的解釋,說是.NET每次會自動搜索代理,所以很慢,此處沒有設置代理的話,應該直接復制為空:

req.Proxy = null;

然后再去執行GetRequestStream,這樣就不會慢了。

然后去試了試,好像是這個效果。

2.結果第二天同樣的代碼,去調試,結果GetRequestStream的地方,還是死掉了。

原因暫未知。

3.后來的情況是,同樣的代碼,再次運行,就不死了,雖然也還是有時候效率低,反應慢,但是不會死了。具體根本原因,感覺還是沒有找到。

4. 后來的多次調試,發現對於:

req.Proxy = null;

好像也沒啥效果。

只是碰巧找到了,關於設置proxy為null的原始的官方的解釋:

”C# 3.0 in a Nutshell, Third Edition: A Desktop Quick Reference“的Chapter 14. Networking

Warning

If you don’t have a proxy, you must set the Proxy property to null on all WebClient and WebRequest objects. Otherwise, the Framework may attempt to "auto-detect" your proxy settings, adding up to 30 seconds to your request. If you’re wondering why your web requests execute slowly, this is probably it!

但是此處,對於我所遇到的,執行GetRequestStream會死掉的問題,還是沒有啥幫助。

5.多次調試得到的結果是,如果是對於:

Stream postDataStream = req.GetRequestStream();

是單步調試的話,好像很少會死掉.

而如果直接運行,沒有打斷點,那么經常容易死掉.

6.參考:GetRequestStream throws Timeout exception randomly,去試了:

using (Stream postDataStream = req.GetRequestStream())
{
    postDataStream.Write(postBytes, 0, postBytes.Length);
    postDataStream.Close();
}

還是會死掉。

7.網上看到:HttpWebRequest.GetRequestStream() hangs,看起來此問題,好像已經是官方承認的一個bug。

不過即使真的是bug,其解釋說是在.NET 4.0 beta2才解決掉,而我此處無法用.NET 4.0,只能用.NET 2.0/3.0/3.5,所以,如果真是bug的話,那就真的悲劇了。。。

還是先去看看,有沒有其他解決辦法再說吧。

8.試了如下代碼:

try
{
    Stream postDataStream = req.GetRequestStream();

    postDataStream.Write(postBytes, 0, postBytes.Length);
    postDataStream.Close();
}
catch (WebException ex)
{
    MessageBox.Show(ex.Message);
}

單步調試了:

Stream postDataStream = req.GetRequestStream();

發現經過很長的時間之后,捕獲到了異常WebException ex,出現了“Unable to connect to the remote server”錯誤,其詳細信息如下:

ex	{"Unable to connect to the remote server"}	System.Net.WebException
base	{"Unable to connect to the remote server"}	System.InvalidOperationException {System.Net.WebException}
base	{"Unable to connect to the remote server"}	System.SystemException {System.Net.WebException}
base	{"Unable to connect to the remote server"}	System.Exception {System.Net.WebException}
_className	null	string
_data	null	System.Collections.IDictionary
_dynamicMethods	null	object
_exceptionMethod	null	System.Reflection.MethodBase
_exceptionMethodString	null	string
_helpURL	null	string
_HResult	-2146233079	int
_innerException	{"A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 65.55.254.42:443"}	System.Exception {System.Net.Sockets.SocketException}
_message	"Unable to connect to the remote server"	string
_remoteStackIndex	0	int
_remoteStackTraceString	null	string
_source	null	string
_stackTrace	{sbyte[96]}	object {sbyte[]}
_stackTraceString	null	string
_xcode	-532459699	int
_xptrs	0	System.IntPtr
Data	{System.Collections.ListDictionaryInternal}	System.Collections.IDictionary {System.Collections.ListDictionaryInternal}
HelpLink	null	string
HResult	-2146233079	int
InnerException	{"A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 65.55.254.42:443"}	System.Exception {System.Net.Sockets.SocketException}
IsTransient	false	bool
Message	"Unable to connect to the remote server"	string
Source	"System"	string
StackTrace	"   at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)\r\n   at System.Net.HttpWebRequest.GetRequestStream()\r\n   at InsertSkydriveFiles.skydrive.beforeUploadFile()"	string
TargetSite	{System.IO.Stream GetRequestStream(System.Net.TransportContext ByRef)}	System.Reflection.MethodBase {System.Reflection.RuntimeMethodInfo}
Static members		
InternalStatus	ServicePointFatal	System.Net.WebExceptionInternalStatus
m_InternalStatus	ServicePointFatal	System.Net.WebExceptionInternalStatus
m_Response	null	System.Net.WebResponse
m_Status	ConnectFailure	System.Net.WebExceptionStatus
Response	null	System.Net.WebResponse
Status	ConnectFailure	System.Net.WebExceptionStatus

此處覺得很不能理解的事情是,我只是調用GetRequestStream,獲得request的stream,又不是來自服務器端的response,為何也要去鏈接remote server,而不是本地調用一個庫函數,獲得對應的stream???

 

【后記 2012-03-01】

后來發現,好像此問題,和GetResponse偶爾死掉,是同一個原因,然后也解決了這個問題,具體過程和辦法,請參考:

【已解決】HttpWebRequest的GetResponse或GetRequestStream偶爾超時 + 總結各種超時死掉的可能和相應的解決辦法


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM