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

    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)    at System.Net.HttpWebRequest.GetRequestStream()    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

  • 相关阅读:
    android: 建立和断开a2dp link 相关方法总结
    Java: volatile和synchronized的区别 (转)
    shell 将变量当命令执行的几种方式
    tcp 自连接(主机的端口和自己建立连接)
    sed使用
    海尔风冷冰箱冷冻室最底层结冰 问题解决
    k8s 传参数的两种方式一种是 环境变量 拼接 另一种说是yaml传参到配置文件的表示怀疑要验证????????????????????????????
    k8s 集群中的etcd故障解决
    dockerfile
    使用VIM/VI给文件加密和解密
  • 原文地址:https://www.cnblogs.com/1175429393wljblog/p/11678266.html
Copyright © 2020-2023  润新知