请求没有在.net中等待响应

本文关键字:等待 响应 net 请求 | 更新日期: 2023-09-27 18:19:00

我有一个windows服务,它正在上传文件到另一个正在处理它们的网站。问题是,对于小文件,它工作得很好,并且从那里得到响应,但是对于大文件(大约6分钟处理),它永远处于等待模式。

这里是外部网站post方法代码的一部分:

try
{
  ...
  LogResults();
  return string.Empty;
}
catch (Exception e)
{
  return e.Message;
}

问题是我甚至可以看到大文件的日志,所以这意味着网站总是返回值,但对于大文件,我的windows服务不会等待它们。

下面是windows service

的代码
var valuesp = new NameValueCollection
{
     { "AccountId", datafeed.AccountId }
};
byte[] resultp = UploadHelper.UploadFiles(url, uploadFiles, valuesp);
response = Encoding.Default.GetString(resultp);

UploadFiles方法对于小文件返回值,但是对于大文件永远等待。

这里是UploadFiles

的完整代码
public static byte[] UploadFiles(string address, IEnumerable<UploadFile> files, NameValueCollection values)
{
    var request = WebRequest.Create(address);
    request.Timeout = System.Threading.Timeout.Infinite; //3600000; // 60 minutes
    request.Method = "POST";
    var boundary = "---------------------------" +
                   DateTime.Now.Ticks.ToString("x", NumberFormatInfo.InvariantInfo);
    request.ContentType = "multipart/form-data; boundary=" + boundary;
    boundary = "--" + boundary;
    using (var requestStream = request.GetRequestStream())
    {
        // Write the values
        if (values != null)
        {
            foreach (string name in values.Keys)
            {
                var buffer = Encoding.ASCII.GetBytes(boundary + Environment.NewLine);
                requestStream.Write(buffer, 0, buffer.Length);
                buffer =
                    Encoding.ASCII.GetBytes(string.Format("Content-Disposition: form-data; name='"{0}'"{1}{1}", name,
                                                          Environment.NewLine));
                requestStream.Write(buffer, 0, buffer.Length);
                buffer = Encoding.UTF8.GetBytes(values[name] + Environment.NewLine);
                requestStream.Write(buffer, 0, buffer.Length);
            }
        }
        // Write the files
        if (files != null)
        {
            foreach (var file in files)
            {
                var buffer = Encoding.ASCII.GetBytes(boundary + Environment.NewLine);
                requestStream.Write(buffer, 0, buffer.Length);
                buffer =
                    Encoding.UTF8.GetBytes(
                        string.Format("Content-Disposition: form-data; name='"{0}'"; filename='"{1}'"{2}", file.Name,
                                      file.Filename, Environment.NewLine));
                requestStream.Write(buffer, 0, buffer.Length);
                buffer =
                    Encoding.ASCII.GetBytes(string.Format("Content-Type: {0}{1}{1}", file.ContentType,
                                                          Environment.NewLine));
                requestStream.Write(buffer, 0, buffer.Length);
                requestStream.Write(file.Stream, 0, file.Stream.Length);
                buffer = Encoding.ASCII.GetBytes(Environment.NewLine);
                requestStream.Write(buffer, 0, buffer.Length);
            }
        }
        var boundaryBuffer = Encoding.ASCII.GetBytes(boundary + "--");
        requestStream.Write(boundaryBuffer, 0, boundaryBuffer.Length);
    }
    using (var response = request.GetResponse())
    using (var responseStream = response.GetResponseStream())
    using (var stream = new MemoryStream())
    {
        responseStream.CopyTo(stream);
        return stream.ToArray();
    }
}

我哪里做错了?

EDIT:本地它甚至工作7-8分钟的处理。但在生活环境中却没有。它可以与主应用程序IIS设置相关吗?是否与windows服务服务器设置有关?

EDIT 2:远程服务器web。配置httpRuntime设置

<httpRuntime enableVersionHeader="false" maxRequestLength="300000" executionTimeout="12000" targetFramework="4.5" />

请求没有在.net中等待响应

问题出在Azure Load Balancer上,它的Idle Timeout默认设置为4分钟。Windows Azure博客的新帖子说,这个超时现在可以配置为4-30分钟之间的值

http://azure.microsoft.com/blog/2014/08/14/new-configurable-idle-timeout-for-azure-load-balancer/

然而,通过TCP发送额外的KeepAlive字节解决了这个问题,这告诉负载均衡器不要杀死请求。

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(address);
...
request.Proxy = null;
request.ServicePoint.SetTcpKeepAlive(true, 30000, 5000); //after 30 seconds, each 5 second

将Proxy设置为null(不使用Proxy)是强制操作,因为否则Proxy将不会向服务器传递tcp字节。

使用符合RFC1867的方法上传文件

看到这个

然后:

 UploadFile[] files = new UploadFile[]
{
new UploadFile(fileName1),
new UploadFile(fileName2)
};
NameValueCollection form = new NameValueCollection();
form["name1"] = "value1";
form["name2"] = "xyzzy";
string response = UploadHelper.Upload(url, files, form);

大家好!

EDIT:

我使用上面的方法来上传大小超过100MB的文件,我根本不使用ASP,它工作得很完美!

我有一个类似的问题,上传将在本地工作,但在服务器上超时。这里有两件事在起作用——我假设你说的是IIS7+。如果没有,让我知道,我会很乐意删除我的回答。

首先是ASP。. NET查看此设置(在system.web下):

<!-- maxRequestLength is in KB - 10 MB here. This is needed by ASP.NET. Must match with maxAllowedContentLength under system.webserver/security/requestLimits -->
<httpRuntime targetFramework="4.5" maxRequestLength="1048576" />

然后是IIS:

<system.webServer>
    <security>
        <requestFiltering>
            <!-- maxAllowedContentLength in bytes - 10MB -->
            <requestLimits maxAllowedContentLength="10485760" />
        </requestFiltering>
    </security>
<system.webServer>

您需要这两个设置都存在,并且需要匹配的限制才能工作。注意,一个以KB为单位,另一个以字节为单位。

是否检查了远程服务器上的IIS文件大小限制?默认为30MB,因此如果您尝试上传的文件大于30MB,则会失败。以下是如何更改上载限制(IIS7): http://www.web-site-scripts.com/knowledge-base/article/AA-00696/0/Increasing-maximum-allowed-size-for-uploads-on-IIS7.html

您可以使用AsyncCallback技术实现此任务。

什么是AsyncCallback?

当async方法完成处理后,自动调用AsyncCallback方法,其中可以执行后处理stmts。使用这种技术,不需要轮询或等待异步线程完成。

你可以从这个链接找到更多的细节

AsynCallback

可能是IIS上传限制造成的?在IIS7中,标准值是30MB。看到MSDN

EDIT1:请注意,如果您在一个请求中上传多个文件,则大小总和。

EDIT2:在所有MS示例中总是只有一个Stream.Write()。在MSDN中声明:在Stream对象被返回后,你可以通过使用Stream发送HttpWebRequest数据。写方法。我对这句话的解释是你应该只调用Write()一次。将您想要发送的所有数据放入缓冲区,然后调用Write()。

您应该将executionTimeout="12000"更改为executionTimeout="360000",这意味着将执行超时时间从2分钟更改为6分钟。