C# GetRequestAsync究竟是如何工作的?
我想我遗漏了一些关于HttpWebRequest在上传大文件时如何通过流媒体工作的信息。 基本上,我发现我在向服务器发送大文件时收到超时异常,因此一篇帖子建议通过Async执行此操作,并自行处理超时 问题是,在调试之后,我发现“GetRequestStreamAsync”方法,并且在服务器端写入该方法不起任何作用,只有在执行GetResponseAsync时才调用服务器 所以我的问题是: -代码标记为//1-它将文件写入请求流,但我看不到内存在增加,或者服务器甚至没有收到任何请求-流到哪里? 这是我的基本代码:C# GetRequestAsync究竟是如何工作的?,c#,rest,asynchronous,httpwebrequest,C#,Rest,Asynchronous,Httpwebrequest,我想我遗漏了一些关于HttpWebRequest在上传大文件时如何通过流媒体工作的信息。 基本上,我发现我在向服务器发送大文件时收到超时异常,因此一篇帖子建议通过Async执行此操作,并自行处理超时 问题是,在调试之后,我发现“GetRequestStreamAsync”方法,并且在服务器端写入该方法不起任何作用,只有在执行GetResponseAsync时才调用服务器 所以我的问题是: -代码标记为//1-它将文件写入请求流,但我看不到内存在增加,或者服务器甚至没有收到任何请求-流到哪里? 这
HttpWebRequest request = RESTUtils.InitializeRequest(...);
request.AllowWriteStreamBuffering = false;
request.ContentLength = i_InputStream.Length;
request.Timeout = 5000;
using (Stream requestStream = request.GetRequestStreamWithTimeout())
{
if (requestStream != null) //1
{
// We will write the stream to the request
byte[] buffer = new byte[UPLOAD_FILE_BUFFER_SIZE];
int read = i_InputStream.Read(buffer, 0, buffer.Length);
while (read > 0)
{
requestStream.Write(buffer, 0, read);
read = i_InputStream.Read(buffer, 0, buffer.Length);
}
}
}
using (var response = request.GetResponseWithTimeout(-1))
{
using (var responseStream = response.GetResponseStream())
{
}
}
public static class WebRequestExtensions
{
public static Stream GetRequestStreamWithTimeout(
this WebRequest request,
int? millisecondsTimeout = null)
{
return AsyncToSyncWithTimeout(
request.BeginGetRequestStream,
request.EndGetRequestStream,
millisecondsTimeout ?? request.Timeout);
}
public static WebResponse GetResponseWithTimeout(
this HttpWebRequest request,
int? millisecondsTimeout = null)
{
return AsyncToSyncWithTimeout(
request.BeginGetResponse,
request.EndGetResponse,
millisecondsTimeout ?? request.Timeout);
}
private static T AsyncToSyncWithTimeout<T>(
Func<AsyncCallback, object, IAsyncResult> begin,
Func<IAsyncResult, T> end,
int millisecondsTimeout)
{
var iar = begin(null, null);
if (!iar.AsyncWaitHandle.WaitOne(millisecondsTimeout))
{
var ex = new TimeoutException();
throw new WebException(ex.Message, ex, WebExceptionStatus.Timeout, null);
}
return end(iar);
}
}
HttpWebRequest-request=RESTUtils.InitializeRequest(…);
request.AllowWriteStreamBuffering=false;
request.ContentLength=i_InputStream.Length;
请求超时=5000;
使用(Stream requestStream=request.GetRequestStreamWithTimeout())
{
if(requestStream!=null)//1
{
//我们将把流写入请求
byte[]buffer=新字节[上传文件\缓冲区大小];
int read=i_InputStream.read(buffer,0,buffer.Length);
while(读取>0)
{
写入(缓冲区,0,读取);
read=i_InputStream.read(buffer,0,buffer.Length);
}
}
}
使用(var response=request.GetResponseWithTimeout(-1))
{
使用(var responseStream=response.GetResponseStream())
{
}
}
公共静态类WebRequestExtensions
{
公共静态流GetRequestStreamWithTimeout(
此WebRequest请求,
int?毫秒刺激值=零)
{
返回AsyncToSyncWithTimeout(
request.BeginGetRequestStream,
request.EndGetRequestStream,
毫秒刺激??请求超时);
}
公共静态WebResponse GetResponseWithTimeout(
此HttpWebRequest请求,
int?毫秒刺激值=零)
{
返回AsyncToSyncWithTimeout(
request.BeginGetResponse,
request.EndGetResponse,
毫秒刺激??请求超时);
}
专用静态T AsyncToSyncWithTimeout(
Func begin,
完,,
整数毫秒(秒)
{
var iar=begin(null,null);
如果(!iar.AsyncWaitHandle.WaitOne(毫秒)
{
var ex=新的TimeoutException();
抛出新的WebException(例如Message、ex、WebExceptionStatus.Timeout、null);
}
返回端(iar);
}
}
谢谢
==编辑9/9/15==
更奇怪的事情发生了,我在GetResponseAsync之后附加断点,然后我看到服务器收到了调用。
之后,我将关闭客户端->服务器成功上传文件的过程
如果我执行“中止”,也会发生这种情况。
有人知道为什么吗?
不要使用旧式的开始/结束异步模式,你应该考虑切换到大大简化你的代码。
然后将请求的Timeout
属性设置为一个大值,以适应等待时间;然后,您不必使用基于回调的异步代码,只需执行以下操作:
var request = SomeMethodToCreateRequest();
request.Timeout = int.MaxValue; // (don't do this)
var response = await request.GetResponse();
超时应该在内部得到尊重,你可以简化你的代码。
而不是使用旧风格的开始/结束异步模式,你应该考虑切换到大大简化你的代码。
然后将请求的Timeout
属性设置为一个大值,以适应等待时间;然后,您不必使用基于回调的异步代码,只需执行以下操作:
var request = SomeMethodToCreateRequest();
request.Timeout = int.MaxValue; // (don't do this)
var response = await request.GetResponse();
应该在内部遵守超时,您可以简化代码。AsyncToSyncWithTimeout在超时情况下无法调用end。这是资源泄漏。为什么要切换到异步?这与流超时无关。使用@usr我知道泄漏,这只是一个示例代码。我无法传输大文件,客户端超时刚刚弹出。Async没有使用那个超时,所以我选择了这个方向。@我更喜欢使用这个方法,我搜索了Httpclient,发现所有实现都使用多部分表单,但我没有在服务器端使用表单,它的普通流式处理。AsyncToSyncWithTimeout在超时情况下无法调用end。这是资源泄漏。为什么要切换到异步?这与流超时无关。使用@usr我知道泄漏,这只是一个示例代码。我无法传输大文件,客户端超时刚刚弹出。Async不使用那个超时,所以我选择了这个方向。@我更喜欢使用这个方法,我搜索了Httpclient,发现所有实现都使用多部分表单,但我不在服务器端使用表单,它是纯流式的。我不想设置大的超时。服务器使用wcf进行流式传输。如果服务器不可用,大超时将导致延迟。我不想设置大超时。服务器使用wcf进行流式传输。如果服务器不可用,大超时将导致延迟。