强制异步WebRequest刷新其缓冲区c#

时间:2016-03-10 12:26:05

标签: c# asynchronous httpwebrequest flush

我有以下连接代码:

_request = (HttpWebRequest)WebRequest.Create(complianceUrl);
_request.Method = "GET";

var authInfo = string.Format("{0}:{1}", _username, _password);
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
_request.Headers.Add("Authorization", "Basic " + authInfo);

// set stream parameters
_request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
_request.Headers.Add("Accept-Encoding", "gzip");
_request.Accept = "application/json";
_request.ContentType = "application/json";
_request.ReadWriteTimeout = 30000;
_request.AllowReadStreamBuffering = false;

_request.Timeout = 30; //seconds, sends 15-second heartbeat.
_asyncCallback = HandleResult;    //Setting handleResult as Callback method...
_request.BeginGetResponse(_asyncCallback, _request);    //Calling BeginGetResponse on 

这很好用,缓冲区填充数据,而我有大量的数据,这很好。但是由于数据量很小,缓冲区需要一段时间才能填满,如果我有一段时间没有任何活动,我想定期刷新缓冲区。

我试着这样做:

_request.GetRequestStream().FlushAsync();

但这是错误的,因为它告诉我我正在导致一个ProtocolViolationException,我猜这是一个GET动词?

有人能告诉我如何强制连接将缓冲区转储到客户端吗?

处理添加的响应代码:

private void HandleResult(IAsyncResult result)
{
    using (var response = (HttpWebResponse) _request.EndGetResponse(result))
    using (var stream = response.GetResponseStream())
    using (var memory = new MemoryStream())
    {
        var compressedBuffer = new byte[BlockSize];

        while (stream != null && stream.CanRead)
        {
            var readCount = stream.Read(compressedBuffer, 0, compressedBuffer.Length);

            // if readCount is 0, then the stream must have disconnected.  Process and abort!
            if (readCount == 0)
            {

            }
        }
    }
}

2 个答案:

答案 0 :(得分:0)

无法使HTTP调用的服务器端以特定方式向您发送数据。 HTTP和TCP都没有规定。你必须拿走你得到的东西,或者与供应商交谈。

在缓冲区已满之前,

check<-function(R) { s<-list(M) if(R > 50) { s<-list(M) } return(s) } out<-sapply(R,check); 不会阻塞。它会立即为您提供所需的信息。这种行为众所周知,这不是我的猜测。

  

第三方服务发送15秒心跳CRLF,最终也会填满缓冲区。

这听起来就像服务正在做你想要的。如果是这样,问题必须出在您的代码中。但不是在问题中显示的代码中。试试这个:

Read

这应该每15秒显示2个字节。如果没有,供应商就有错。如果是的话,你就是。

while (true) { var readCount = stream.Read(compressedBuffer, 0, compressedBuffer.Length); Console.WriteLine(readCount); } 这很奇怪,因为这些条件都不会变错。即使它们变得虚假,你会怎么做呢?!在流消耗时应该while (stream != null && stream.CanRead)while (true)

break

这种情况意味着远程端已经有序地完成了HTTP响应的发送。

答案 1 :(得分:0)

对于任何感兴趣的人,您可以手动阅读和缩减执行以下操作:

using (var response = (HttpWebResponse) _request.EndGetResponse(result))
using (var stream = response.GetResponseStream())
using (var compressedMemory = new MemoryStream())
using (var uncompressedMemory = new MemoryStream()) // Added new memory stream
using (var gzipStream = new GZipStream(compressedMemory, CompressionMode.Decompress))
{
    var compressedBuffer = new byte[BlockSize];

    while (stream != null && stream.CanRead)
    {
        var readCount = stream.Read(compressedBuffer, 0, compressedBuffer.Length);

        compressedMemory.Write(compressedBuffer.Take(readCount).ToArray(), 0, readCount);
        compressedMemory.Position = 0;

        gzipStream.CopyTo(uncompressedMemory); // use copy to rather than trying to read

        var outputString = Encoding.UTF8.GetString(uncompressedMemory.ToArray());
        Debug.WriteLine(outputString);

        uncompressedMemory.Position = 0;
        uncompressedMemory.SetLength(0);

        compressedMemory.Position = 0;
        compressedMemory.SetLength(0); // reset length
    }
}