2015-10-12 3 views
0

У меня есть веб-сайт, которому нужно позвонить в веб-службу от 1 до 10000 раз. В настоящее время это делается в цикле по каждому что-то вроде этого:Лучшая техника для потокового вызова веб-службы

List<Address> addresses 
List<Response> responses = new List<Response>(); 
foreach(Address address in addresses){ 
    //Setup web service call 
    //Call web service 
    //Parse response into object for front end 
    responses.Add(CustomReponseObject) 
} 
// The responses object is then just serialized and set to the front end client to parse through. 

Нынешний подход не имеет резьбу, и я хотел бы, чтобы ускорить его. Не уверен, что я должен использовать управляемые потоки или перейти с новыми ключевыми словами Async Await.

Я начал этот процесс, а затем повесил трубку, если новое ключевое слово Async может работать, используя блокировку в списке ответов или может потребоваться что-то вроде ConcurrentBag? Я прочитал все три варианта, но не знаю, какой вариант лучше всего подходит для моего варианта использования?

+0

Можете ли вы показать пример, как 'async' является альтернативой' ConcurrentBag'? (Обратите внимание, что в целом вопросы «наилучшего подхода» основаны на мнениях/слишком широки без конкретной цели. В настоящее время у вас нет ничего, что показывает, почему ваш нынешний подход неприемлем) –

ответ

1

Вы должны использовать async/wait, потому что это минимизирует использование управляемых потоков, ожидая завершения операций ввода-вывода для выполнения веб-сервисов.

Существует full example on MSDN, показывающий этот точный шаблон.

Что касается контейнера, вам необходимо будет контролировать доступ к списку при добавлении через блокировку при добавлении каждого потока, если вы используете List<T>, поскольку этот класс не является потокобезопасным при изменении (несколько потоков могут считываться одновременно).

Лучшим выбором является ConcurrentQueue<T>, так как он оптимизирован для этой схемы чтения/записи (спасибо @Scott для наблюдения).

+0

Вы действительно имели в виду место блокировки самого объекта списка? Я предпочитаю отдельный частный объект блокировки. –

+0

@RobertHarvey: Нет, я всегда использую закрытый объект блокировки. Я сделаю это более ясным в своем ответе. –

+0

Еще один момент, касающийся 'ConcurrentBag ', оптимизирован для ситуаций, когда один и тот же поток вставляет и вытаскивает из сумки (например, пул объектов, в котором много потоков берут и возвращают элементы в пул), это называется «Смешанный сценарий производителя-потребителя». Для «чистого сценария производителя-потребителя», где поток либо добавляет, либо удаляет из коллекции, но не имеет значения «ConcurrentQueue ». См. Статью MSDN «[Когда использовать сборку с потоками» (https://msdn.microsoft.com/en-us/library/dd997373.aspx) »для получения дополнительной информации. –

Смежные вопросы