我有一个 Windows 服务,它正在将文件上传到正在处理它们的其他网站。问题是,对于小文件,它工作正常并且从那里得到响应,但是对于大文件(处理大约 6 分钟),它永远处于等待模式。
外部网站post方法部分代码如下:
try
{
...
LogResults();
return string.Empty;
}
catch (Exception e)
{
return e.Message;
}
问题是我什至可以看到大文件的日志,所以这意味着网站总是返回值,但对于大文件,我的 Windows 服务不会等待它们。
这是windows服务的代码
var valuesp = new NameValueCollection
{
{ "AccountId", datafeed.AccountId }
};
byte[] resultp = UploadHelper.UploadFiles(url, uploadFiles, valuesp);
response = Encoding.Default.GetString(resultp);
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();
}
}
我做错了什么?
编辑: 在本地它甚至可以处理 7-8 分钟。但在现场环境中没有。它可以与主应用程序 IIS 设置相关吗?会不会和windows服务服务器设置有关?
编辑 2: 远程服务器 web.config httpRuntime 设置
<httpRuntime enableVersionHeader="false" maxRequestLength="300000" executionTimeout="12000" targetFramework="4.5" />
最佳答案
问题出在 Azure 负载均衡器上,它的空闲超时默认设置为 4 分钟。 Windows Azure 博客的新帖子说这个超时现在可以配置为 4-30 分钟之间的值
http://azure.microsoft.com/blog/2014/08/14/new-configurable-idle-timeout-for-azure-load-balancer/
但是,通过 TCP 发送额外的 KeepAlive 字节解决了这个问题,这告诉 Load Balancer 不要终止请求。
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(address);
...
request.Proxy = null;
request.ServicePoint.SetTcpKeepAlive(true, 30000, 5000); //after 30 seconds, each 5 second
将 Proxy 设置为 null(不使用代理)是此处的强制操作,否则代理将不会将 tcp 字节传递给服务器。
关于c# - .net 中请求不等待响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25423834/