@Sendo

Как увеличить количество запросов к серверу за минимальное время?

Здравствуйте, сразу прошу извинить за свою тупость(Только начинаю учить c#), но написать данную программу очень сильно нужно. Проблема в том что я отправляю на сервер запрос:
private string GET(string Url)
        {
            WebRequest req = WebRequest.Create(Url);
            WebResponse resp = req.GetResponse();
            Stream stream = resp.GetResponseStream();
            StreamReader sr = new StreamReader(stream);
            string Out = sr.ReadToEnd();
            sr.Close();
            return Out;
        }


Но мне не нравиться скорость выполнения моей программы. За 10 секунд у меня получается максимально отправить только 20 запрос на разные страницы сайта. Я так понимаю это происходит так:
1) Программа отправляет запрос.
2) Ждем какое то время пока сервер ответит нам(вот тут и самое сложное место, я так думаю)
3) Обрабатывает ответ.
4) Возвращаемся на 1 шаг.
Я правильно понимаю, подскажите пожалуйста?
Возможно ли сделать так:
1) Программа отправляет запрос на 1 страницу.
2) Программа отправляет запрос на 2 страницу.
3) Ждем какое то время пока сервер ответит нам на 1 страницу.
4) Ждем какое то время пока сервер ответит нам на 2 страницу.
5) Обрабатываем ответы.
Есть предположения что для этого нужно использовать потоки... Если не сложно с кодом пожалуйста объясните. Заранее Огромное Спасибо.
  • Вопрос задан
  • 230 просмотров
Решения вопроса 1
AlekseyNemiro
@AlekseyNemiro
full-stack developer
Попробуйте использовать HttpClient:

private async Task<string> Get(string url)
{
  using (var client = new HttpClient())
  {
    using (var r = await client.GetAsync(new Uri(url)))
    {
      return await r.Content.ReadAsStringAsync();
    }
  }
}

Но придется вызов метода Get делать с await, и далее по цепочке вверх, добавлять async/await:

string result = await Get("https://toster.ru/q/470456");

В качестве альтернативного варианта, можно запускать запросы асинхронно и передавать результат выполнения запроса в функцию. С вашим кодом, примерно так:

private void Get(string url)
{
  Task.Run(async () =>
  {
    WebRequest req = WebRequest.Create(url);
    WebResponse resp = await req.GetResponseAsync();
    Stream stream = resp.GetResponseStream();
    StreamReader sr = new StreamReader(stream);

    string result = await sr.ReadToEndAsync();

    sr.Close();

    // передаем результат
    ResultCallback(url, result);
  });
}

private void ResultCallback(string url, string result)
{
  // выводим в консоль результат
  Console.WriteLine(url);
  Console.WriteLine(result);
}

Аналогичный вариант с HttpClient
private void Get(string url)
{
  Task.Run(async () =>
  {
    using (var client = new HttpClient())
    {
      using (var r = await client.GetAsync(new Uri(url)))
      {
        string result = await r.Content.ReadAsStringAsync();

        ResultCallback(url, result);
      }
    }
  });
}
Обертка кода, указанного в тексте вопроса, с минимальными изменениями
private void Get(string url)
{
  // выполняем запрос в отдельном потоке
  Task.Run(() =>
  {
    WebRequest req = WebRequest.Create(url);
    WebResponse resp = req.GetResponse();
    Stream stream = resp.GetResponseStream();
    StreamReader sr = new StreamReader(stream);

    string result = sr.ReadToEnd();

    sr.Close();

    // передаем результат в функцию обратного вызова
    ResultCallback(url, result);
  });
}

private void ResultCallback(string url, string result)
{
  Console.WriteLine(url);
  Console.WriteLine(result);
}
Вариант с оберткой Thread, если используются старая версия .NET
private void Get(string url)
{
  // создаем поток
  var t = new Thread(() =>
  {
    WebRequest req = WebRequest.Create(url);
    WebResponse resp = req.GetResponse();
    Stream stream = resp.GetResponseStream();
    StreamReader sr = new StreamReader(stream);

    string result = sr.ReadToEnd();

    sr.Close();

    ResultCallback(url, result);
  });

  // запускаем
  t.Start();
}

private void ResultCallback(string url, string result)
{
  Console.WriteLine(url);
  Console.WriteLine(result);
}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@BashkaMen
C# программист
Подправлю первый ответ под Ваш вопрос.
string result = await Get("https://toster.ru/q/470456");


await - синхронизирует запрос, а вы как я понял хотите несколько запросов паралельно.

можно так

var task1= Get("https://toster.ru/q/470457");
var task2= Get("https://toster.ru/q/470458");
var task3= Get("https://toster.ru/q/470459");

var result1=task1.Result;
var result2=task2.Result;
var result3=task3.Result;


я думаю переделать под массив сможешь, а это просто пример
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы