C# 请求不';不要在.net中等待响应

C# 请求不';不要在.net中等待响应,c#,.net,request,response,webrequest,C#,.net,Request,Response,Webrequest,我有一个windows服务,它正在将文件上载到另一个正在处理它们的网站。问题是,对于小文件,它工作得很好,并且从那里得到响应,但是对于大文件(大约6分钟的处理时间),它永远处于等待模式 以下是外部网站发布方法代码的一部分: try { ... LogResults(); return string.Empty; } catch (Exception e) { return e.Message; } 问题是,我甚至可以看到大文件的日志,所以这意味着网站总是返回值,但对于大文件,我

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

以下是外部网站发布方法代码的一部分:

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();
    }
}
公共静态字节[]上传文件(字符串地址、IEnumerable文件、NameValueCollection值)
{
var request=WebRequest.Create(地址);
request.Timeout=System.Threading.Timeout.Infinite;//3600000;//60分钟
request.Method=“POST”;
var boundary=“------------------------------------”+
DateTime.Now.Ticks.ToString(“x”,NumberFormatInfo.InvariantInfo);
request.ContentType=“多部分/表单数据;boundary=“+boundary;
边界=“-”+边界;
使用(var requestStream=request.GetRequestStream())
{
//写下这些值
如果(值!=null)
{
foreach(values.Keys中的字符串名称)
{
var buffer=Encoding.ASCII.GetBytes(边界+环境.NewLine);
Write(buffer,0,buffer.Length);
缓冲区=
Encoding.ASCII.GetBytes(string.Format(“内容处置:表单数据;名称=\”{0}\“{1}”),name,
环境(新线),;
Write(buffer,0,buffer.Length);
buffer=Encoding.UTF8.GetBytes(值[name]+Environment.NewLine);
Write(buffer,0,buffer.Length);
}
}
//写文件
如果(文件!=null)
{
foreach(文件中的var文件)
{
var buffer=Encoding.ASCII.GetBytes(边界+环境.NewLine);
Write(buffer,0,buffer.Length);
缓冲区=
Encoding.UTF8.GetBytes(
string.Format(“内容处置:表单数据;名称=\”{0}\“文件名=\”{1}\“{2}”,file.name,
file.Filename,Environment.NewLine));
Write(buffer,0,buffer.Length);
缓冲区=
Encoding.ASCII.GetBytes(string.Format(“内容类型:{0}{1}{1}”),file.ContentType,
环境(新线),;
Write(buffer,0,buffer.Length);
Write(file.Stream,0,file.Stream.Length);
buffer=Encoding.ASCII.GetBytes(Environment.NewLine);
Write(buffer,0,buffer.Length);
}
}
var boundaryBuffer=Encoding.ASCII.GetBytes(边界+“-”);
Write(boundaryBuffer,0,boundaryBuffer.Length);
}
使用(var response=request.GetResponse())
使用(var responseStream=response.GetResponseStream())
使用(var stream=new MemoryStream())
{
responseStream.CopyTo(流);
返回流ToArray();
}
}
我做错了什么

编辑:即使在7-8分钟的处理过程中,它也能在本地工作。但在现实环境中,情况并非如此。它是否与主应用程序IIS设置相关?它是否与windows服务服务器设置相关

编辑2:远程服务器web.config httpRuntime设置

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

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

编辑1: 请注意,如果您在一个请求中上载多个文件,则大小相加

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

是否检查了远程服务器上的IIS文件大小限制?它默认为30MB,因此如果您尝试上载的文件大于30MB,则将失败。下面是如何更改上载限制(IIS7):

您可以使用异步回调技术来完成此任务

什么是异步回调? 当async方法完成处理时,会自动调用AsyncCallback方法,在这里可以执行后处理STMT。使用此技术,无需轮询或等待异步线程完成

您可以从该链接中找到更多详细信息


您应该将此
executionTimeout=“12000”
更改为
executionTimeout=“360000”
这意味着将执行超时从2分钟更改为6分钟

使用符合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);
这就是所有的人

编辑:


我用上面的方法上传超过100MB的文件,我根本不使用ASP,它工作得非常完美

我遇到了一个类似的问题,上传可以在本地工作,但在服务器上超时。这里有两件事在起作用——我假设你说的是IIS7+。如果没有,请告诉我,我很乐意删除我的答案

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


然后是IIS:


您需要同时存在这两个设置,并且需要与瘦的限制相匹配
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(address);
...
request.Proxy = null;
request.ServicePoint.SetTcpKeepAlive(true, 30000, 5000); //after 30 seconds, each 5 second