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

【問題】html

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

Stream postDataStream = req.GetRequestStream();shell

而後填充對應的post數據,再提交http的請求。xcode

可是調試的時候,發現每次執行GetRequestStream都很慢。服務器

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

【解決過程】函數

1.網上找了找,根據 GetRequestStream的效率爲何這麼低? 的解釋,說是.NET每次會自動搜索代理,因此很慢,此處沒有設置代理的話,應該直接複製爲空:post

req.Proxy = null;ui

而後再去執行GetRequestStream,這樣就不會慢了。this

而後去試了試,好像是這個效果。

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,去試了:

1
2
3
4
5
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.試了以下代碼:

1
2
3
4
5
6
7
8
9
10
11
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」錯誤,其詳細信息以下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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

 

原文鏈接:https://www.cnblogs.com/summer_adai/archive/2013/04/26/3045261.html

相關文章
相關標籤/搜索