Бесконечный поток в HttpWebResponse - PullRequest
3 голосов
/ 05 марта 2011

как я могу прочитать несколько байтов и отключиться?я использую такой код

using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
{
    using (Stream sm = resp.GetResponseStream())
    {
        using (StreamReader sr = new StreamReader(sm, Encoding.Default))
        {
            sr.Read();
            sr.Close();
        }
    }
}

, но он ждет окончания потока

Ответы [ 5 ]

5 голосов
/ 05 марта 2011

Вы, вероятно, не хотите использовать StreamReader для чтения потока WebResonse, если вы не уверены, что поток содержит символы новой строки. StreamReader любит мыслить в терминах строк, и если в потоке нет новых строк, он зависнет.

Лучше всего прочитать столько байтов, сколько вы хотите, в буфер byte[], а затем преобразовать это в текст. Например:

int BYTES_TO_READ = 1000;
var buffer = new byte[BYTES_TO_READ];

using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
{
    using (Stream sm = resp.GetResponseStream())
    {
        int totalBytesRead = 0;
        int bytesRead;
        do
        {
            // You have to do this in a loop because there's no guarantee that
            // all the bytes you need will be ready when you call.
            bytesRead = sm.Read(buffer, totalBytesRead, BYTES_TO_READ-totalBytesRead);
            totalBytesRead += bytesRead;
        } while (totalBytesRead < BYTES_TO_READ);

        // Sometimes WebResponse will hang if you try to close before
        // you've read the entire stream.  So you can abort the request.
        request.Abort();
    }
}

На данный момент, буфер имеет первые BYTES_TO_READ байтов из буфера. Затем вы можете преобразовать это в строку, например так:

string s = Encoding.Default.GetString(buffer);

Или вы можете открыть MemoryStream в буфере, если хотите использовать StreamReader.

Я иногда сталкиваюсь с WebResponse зависанием, если вы не все читаете. Я не знаю, почему это происходит, и я не могу надежно воспроизвести это, но я обнаружил, что если я сделаю request.Abort() до закрытия потока, все будет работать. См

На дополнительном примечании нужное вам слово "не отвечает", а не "не отвечает".

4 голосов
/ 05 марта 2011

Не могли бы вы сделать что-то подобное?

        string GetWebPageContent(string url)
        {
            string result = string.Empty;
            HttpWebRequest request;
            const int bytesToGet = 1000;
            request = WebRequest.Create(url) as HttpWebRequest;

//get first 1000 bytes
            request.AddRange(0, bytesToGet - 1);

            using (WebResponse response = request.GetResponse())
            {
                using (StreamReader sr = new StreamReader(response.GetResponseStream()))
                {
                    result = sr.ReadToEnd();
                }
            }
            return result;
        }

Ключ использует AddRange в вашем запросе.

1 голос
/ 02 марта 2018

Это связано с тем, что соединение http 1.1 является постоянным соединением по умолчанию, и соединение tcp не было закрыто, поэтому поток потока не получил конец.

вы можете использовать myHttpWebRequest1.KeepAlive = false; поэтому соединение tcp закроется после ответа http.

https://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.connection(v=vs.110).aspx#

0 голосов
/ 25 марта 2011

У меня был похожий бесконечный анализ запросов с примерами, перечисленными здесь.Вот что я придумал, чтобы устранить эти проблемы:

// url is a string where the request is going.
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;

// Do what you have to do with the Request.

StringBuilder builder = new StringBuilder();
int toRead = 1000;

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
    HttpStatusCode status = response.StatusCode;

    using (Stream receiveStream = response.GetResponseStream())
    {
        using (StreamReader readStream = new StreamReader(receiveStream, Encoding.GetEncoding("utf-8")))
        {
            Char[] read = new Char[toRead];
            int count = readStream.Read(read, 0, toRead);

            while (count > 0)
            {
                string str = new String(read, 0, count);
                builder.Append(str);

                count = readStream.Read(read, 0, toRead);
            }

            readStream.Close();
        }   
    }

    response.Close();
}

return builder.ToString();
0 голосов
/ 05 марта 2011

Если вы говорите о winforms или webforms, я бы поместил запрос в пул потоков (или Task, если вы используете .net 4). Потоки, даже с хорошей обработкой, слишком легко переводить графический интерфейс в состояние ожидания, которое не нравится большинству пользователей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...