Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# GetRequestAsync究竟是如何工作的?_C#_Rest_Asynchronous_Httpwebrequest - Fatal编程技术网

C# GetRequestAsync究竟是如何工作的?

C# GetRequestAsync究竟是如何工作的?,c#,rest,asynchronous,httpwebrequest,C#,Rest,Asynchronous,Httpwebrequest,我想我遗漏了一些关于HttpWebRequest在上传大文件时如何通过流媒体工作的信息。 基本上,我发现我在向服务器发送大文件时收到超时异常,因此一篇帖子建议通过Async执行此操作,并自行处理超时 问题是,在调试之后,我发现“GetRequestStreamAsync”方法,并且在服务器端写入该方法不起任何作用,只有在执行GetResponseAsync时才调用服务器 所以我的问题是: -代码标记为//1-它将文件写入请求流,但我看不到内存在增加,或者服务器甚至没有收到任何请求-流到哪里? 这

我想我遗漏了一些关于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进行流式传输。如果服务器不可用,大超时将导致延迟。