Существует ли хорошая модель многопоточности для множества одновременных http-запросов? - PullRequest
1 голос
/ 06 октября 2011

Моему приложению .Net и Java необходимо отправлять множество одновременных запросов к веб-службе, для ответа на который требуется значительное время.Следовательно, могут быть тысячи невыполненных HTTP-запросов одновременно.Чтобы реализовать это, я мог бы с помощью одного потока генерировать много асинхронных HTTP-запросов и обрабатывать ответы, но я хочу понять любые альтернативы, которые позволяют выполнять синхронные HTTP-запросы без необходимости использования тысяч потоков из-за стоимости связанных ресурсов.Любое решение должно предотвращать блокировку потоков в ожидании ответов HTTP.

Мой вопрос состоит из двух частей:

1) Можно ли использовать Threadpools для этого?Я знаю, что могу поставить свои задания в очередь в пуле потоков, и пул потоков будет обрабатывать их, как и когда это возможно, но могут ли рабочие потоки пулов избежать блокировки в ожидании ответа http?Могут ли они пойти и обработать другие задания, пока они ждут?

2) Есть ли какой-то другой способ, которым я могу достичь этого, сохранив простоту синхронного вызова API-интерфейса HTTP.

С уважением

Ответы [ 2 ]

1 голос
/ 30 мая 2012

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

string[] urls = GetUrls();
var requests = new Dictionary<string, Task<string>>()
var responses = new Dictionary<string, string>();

// send off each request and store the on-going task in a dictionary
foreach (string url in urls)
    requests.Add(url, Task.Factory.StarNew(() => return WebClient.DownloadString(url))

// get the results asynchronously
Task.Factory.StartNew(() => {
    foreach (var request in requests)
        responses.Add(request.key, request.Result)
 }

Теперь, когда вы получите ответ, вы можете сделать это несколькими способами. Выше будет получить результат каждой задачи по одному. Когда вы вызываете результат, он будет ждать завершения задачи, блокируя вызывающий метод, и на этом этапе выдает исключения, если задача не выполнена. Вы также можете подождать весь пакет сразу с помощью Task.WaitAll (); Поскольку вызов .Result блокирует вызывающий метод, вам также придется получать результаты из задачи.

В этом примере предполагается, что вы отправляете HTTP-GET и хотите получить результат в виде строки, но независимо от того, какой метод или результат вы хотите получить, способ выполнения вызова и получения результата будет одинаковым. Вы также хотите добавить обработку исключений, чтобы перехватывать любые исключения, которые могут быть выброшены. Вы можете ознакомиться с обработкой исключений задачи здесь .

1 голос
/ 06 октября 2011

Можно ли использовать Threadpools для этого?

Сами по себе, нет.

Есть ли какой-то другой способ, которым я могу добиться этого, сохраняя простотуHTTP-синхронного вызова API.

Вы говорите о клиентской стороне API вызова HTTP?Если это так, есть способ сделать это, используя асинхронную реализацию на стороне сервера.

...