【問題】
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,去試了:
?
12345 |
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.試了如下代碼:
?
1234567891011 |
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”錯誤,其詳細資料如下:
?
123456789101112131415161718192021222324252627282930313233343536 |
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偶爾死掉,是同一個原因,然後也解決了這個問題,具體過程和辦法,請參考:
http://www.cnblogs.com/summer_adai/archive/2013/04/26/3045253.html