HttpWebRequest:请求已中止:请求已取消

时间:2010-03-17 00:51:25

标签: c# visual-studio-2008 httpwebrequest

我一直致力于开发一个中间人应用程序,它使用一系列日期的HTTP发布请求(通常一次只有7个)将文本上传到CMS后端。我正在使用HttpWebRequest来实现这一目标。它似乎在第一个日期工作正常,但是当它开始第二个日期时,我得到System.Net.WebException:请求被中止:请求被取消。

我四处寻找并找到了以下重要线索:

http://social.msdn.microsoft.com/Forums/en-US/netfxnetcom/thread/0d0afe40-c62a-4089-9d8b-fb4d206434dc

http://www.jaxidian.org/update/2007/05/05/8

http://arnosoftwaredev.blogspot.com/2006/09/net-20-httpwebrequestkeepalive-and.html

他们并没有太多帮助。我试过重载GetWebReuqest,但这没有意义,因为我没有使用该函数。

这是我的代码: http://pastebin.org/115268

在成功运行至少一次后,我在第245行得到错误。

我很感激我能得到的任何帮助,因为这是我一直在努力的项目的最后一步。这是我的第一个C#/ VS项目,所以我愿意接受任何提示,但我想专注于首先解决这个问题。

谢谢!

4 个答案:

答案 0 :(得分:20)

Internet上列出的常见解决方案似乎是将HttpWebRequest的KeepAlive属性设置为false。如果根本原因是连接预期会被重用,即使它在一段时间后实际自动关闭,这也可以解决问题。但是,不断打开和关闭连接会对性能造成影响。

我遇到此问题时使用的另一种可能的解决方案是扩展Timeout属性:WebRequest.ReadWriteTimeout,WebRequest.Timeout,RequestStream.WriteTimeout和RequestStream.ReadTimeout。请注意这些是以毫秒为单位,因此您可能希望超时为1000 * 60 * 10代表10分钟(如果您认为您将知道这意味着什么,则只需600000)。您可以通过减小文件大小来测试是否更有可能导致问题。

顺便说一句。您的代码不再在列出的网站上。如果仍然存在问题,您可能希望将其包含在帖子的文本中。

答案 1 :(得分:12)

这是唯一适合我的解决方案:

http://blogs.msdn.com/b/johan/archive/2006/11/15/are-you-getting-outofmemoryexceptions-when-uploading-large-files.aspx

这些行是关键:

    HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(yourUri);
    wr.KeepAlive = false;
    wr.Timeout = System.Threading.Timeout.Infinite;
    wr.ProtocolVersion = HttpVersion.Version10;

在这里:

wr.AllowWriteStreamBuffering = false;

答案 2 :(得分:3)

我的申请简介: 我有多达16个相同的线程同时进行HTTP请求。这些线程中的每一个都从不同的Web服务器请求以及唯一的本地端点。现在,进行这些调用的函数有3个连续的HTTP请求(到同一个Web服务器)并进行一些聚合。

根据上述链接中公布的解决方案,以下组合适用于我。

System.Net.ServicePointManager.DefaultConnectionLimit = 200;
System.Net.ServicePointManager.MaxServicePointIdleTime = 2000;
System.Net.ServicePointManager.MaxServicePoints = 1000;
System.Net.ServicePointManager.SetTcpKeepAlive(false, 0, 0);

HttpWebRequest webRequest1 = (HttpWebRequest)WebRequest.Create("http://" + gatewayIP
 + "/xslt?");
webRequest1.KeepAlive = false;
webRequest1.Timeout = 2000;
//Do other stuff here...
//Close response stream

Thread.Sleep(1000); //This delay seems to help. Obviously very specific to the server

HttpWebRequest webRequest2 = (HttpWebRequest)WebRequest.Create("http://" + gatewayIP
 + "/xslt?");
webRequest2.KeepAlive = false;
webRequest2.Timeout = 2000;
//Do other stuff here...
//and so on...

答案 3 :(得分:1)

我支持Azure Web服务,该服务通过将传入请求的流复制到传出HttpWebRequest的流,例如从移动应用程序接收文件并将其传输到Azure Blob存储。

using (Stream requestStream = outgoingRequest.GetRequestStream()) 
{ 
    context.Request.InputStream.copyTo(requestStream)
    requestStream.Flush();
    requestStream.Close();
}

每隔一段时间,它会在Close()或(如果不包括)Close()结束时抛出“请求被中止:请求已取消”异常。我尝试了上面所有建议的解决方案,但在我发现要在此处共享的错误的真正原因之前,这些解决方案都没有起作用:有时,传入请求的InputStream被切断,并且不包含完整的文件内容。当将此不完整的流复制到传出请求的流时,传出请求在Close()期间或using {}块末尾引发错误。这有点误导,因为原因不是传出请求而是
复制到其中的不完整流。 避免这种情况的方法是添加对传入请求流长度的检查,以比较需要存储在调用应用程序标头中的文件长度,例如

    if (context.Request.InputStream.Length != int.Parse(context.Request.Headers["file-length"])) 
    { 
        //handle this case here, e.g.
        context.Response.StatusCode = 500;
        context.Response.StatusDescription = "(500) Internal Server Error";
        context.Response.End();
    }
    else
    {
         //proceed with copying the stream (the first code snippet)
    }