GetRequestStream 随机抛出超时异常

9

在谷歌上搜索了几天后,我真的无法解决所描述的问题。希望在这里能找到解决方案。

当我在同一台服务器上调用WCF服务时,使用附加的代码。我在调用WebReq.GetRequestStream()时随机收到超时错误。

当我检查netstat时,我看到连接保持打开状态,所以可能存在问题,但我不知道如何解决它。

       //request inicialization
        HttpWebRequest WebReq = (HttpWebRequest)WebRequest.Create(url);
        WebReq.Method = "POST";
        WebReq.ContentType = "application/json; charset=utf-8";
        WebReq.ContentLength = buffer.Length;

        WebReq.Proxy = null;
        WebReq.KeepAlive = false; //also tried with true
        WebReq.AllowWriteStreamBuffering = false; //also tried with true

        //this produces an error
        using (Stream PostData = WebReq.GetRequestStream())
        {
            PostData.Write(buffer, 0, buffer.Length);
            PostData.Close();
        }

         //open and read response
         HttpWebResponse WebResp = (HttpWebResponse)WebReq.GetResponse();
         Stream Answer = WebResp.GetResponseStream();
         StreamReader _Answer = new StreamReader(Answer);

         WebResp.Close();

         //return string
         return _Answer.ReadToEnd();

大多数情况下,超时是在空闲时间达到约10秒后抛出的,但也可能在连续五个请求之后发生。真的找不到任何规律。

这段代码有什么问题?还有没有其他更好的调用WCF服务的方法?

4个回答

14

我不确定它是否绝对是问题的原因,但您只有在没有抛出异常时才关闭Web响应,并且从未关闭响应流。请使用using语句:

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
    return reader.ReadToEnd();
}
这可能很好地解释了问题,因为如果您保持响应打开,它将保持与网络服务器的连接打开,这意味着连接池无法使用该连接。

我没有注意到它在同一台机器上...我想知道你是否正在耗尽线程池线程 - 这些线程是否在同一个进程中? - Jon Skeet
我在.NET编程方面还是新手。之前已经用PHP编程了几年,从来没有遇到过这样的问题。有些事情要简单得多。所以我不确定你所说的“超出线程池线程”是什么意思?在一个请求中,我创建了两个或更多的HTTP请求到WCF服务,因此它们都在同一个进程/请求中。我应该为这些请求使用缓存吗? - AnzeR
@AnzeR:我相信WCF将从线程池中提供请求;如果您从服务本身调用服务,则可能会出现死锁,如果没有更多的线程池线程可用。您并没有真正解释调用代码是什么-它是否在同一个服务内,还是一个单独的应用程序? - Jon Skeet
如果我在调试模式下运行应用程序,它会在 Stream PostData = WebReq.GetRequestStream() 处停止,并在一两分钟后抛出超时异常。这应该是某个先前请求的结果,但我真的不知道是哪一个。 - AnzeR
我不确定这是连接问题。因为它不依赖于已建立的TCP连接数量。我粘贴了调试日志http://pastebin.com/m1aebd069,所以应该有一些有用的信息。 - AnzeR
显示剩余5条评论

6

我曾经遇到过同样的问题,添加一个调用HttpWebRequest.Abort()的方法似乎解决了这个问题。


谢谢!帮我解决了问题。记住:始终正确关闭连接 ;) - pila

0

因为这是非常奇怪的行为,我想知道是否有其他调用同一IIS服务器上托管的WCF服务的方法。 我也认为,为这种调用创建TCP连接并不是真正优化的方式,所有其他方法应该更快。


0

首先要记住的是要检查发送的URI、参数和头部,特别是:

  • 保留字符。通过URI发送保留字符可能会带来问题 ! * ' ( ) ; : @ & = + $ , / ? # []
  • URI长度:不应超过2000个字符
  • 头部长度:大多数Web服务器确实限制它们接受的头部大小。例如,在Apache中,默认限制为8KB。

请记住,如果您想发送更长的数据,建议将其发送到消息正文中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接