Как зайти в Даркнет?!
25th January, 01:11
6
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
894
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
914
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
905
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4350
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4396
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Лучшая Практика Многопоточного Проектирования
Рассмотрим эту проблему: у меня есть программа, которая должна получить (скажем) 100 записей из базы данных, а затем для каждой из них она должна получить обновленную информацию из веб-службы. Есть два способа ввести параллелизм в этом сценарии:
Я запускаю каждый запрос к веб-службе в новом потоке. Количество одновременных потоков контролируется каким-то внешним параметром (или динамически настраивается каким-то образом).
Я создаю меньшие партии (скажем, по 10 записей в каждой) и запускаю каждую партию в отдельном потоке (так что возьмем наш пример, 10 потоков).
Какой подход лучше, и почему вы так думаете?
Вариант 3-самый лучший:
Используйте Async IO.
Если обработка ваших запросов не является сложной и тяжелой, ваша программа будет тратить 99% своего времени на ожидание HTTP запросов.
Это именно то, для чего предназначена Async IO - пусть сетевой стек windows (или фреймворк .net или что-то еще) беспокоится о всех ожиданиях и просто использует один поток для отправки и 'pick up' результатов.
К сожалению, фреймворк .NET делает его настоящей занозой в заднице. Это проще, если вы просто используете необработанные сокеты или Win32 api. Вот такой (проверенный!) пример использования C#3 в любом случае:
using System.Net; // need this somewhere
// need to declare an class so we can cast our state object back out
class RequestState {
public WebRequest Request { get; set; }
}
static void Main( string[] args ) {
// stupid cast neccessary to create the request
HttpWebRequest request = WebRequest.Create( "http://www.stackoverflow.com" ) as HttpWebRequest;
request.BeginGetResponse(
/* callback to be invoked when finished */
(asyncResult) => {
// fetch the request object out of the AsyncState
var state = (RequestState)asyncResult.AsyncState;
var webResponse = state.Request.EndGetResponse( asyncResult ) as HttpWebResponse;
// there we go;
Debug.Assert( webResponse.StatusCode == HttpStatusCode.OK );
Console.WriteLine( "Got Response from server:" + webResponse.Server );
},
/* pass the request through to our callback */
new RequestState { Request = request }
);
// blah
Console.WriteLine( "Waiting for response. Press a key to quit" );
Console.ReadKey();
}
EDIT:
В случае .NET 'completion callback' фактически запускается в потоке ThreadPool, а не в вашем основном потоке, поэтому вам все равно нужно будет заблокировать любые общие ресурсы, но это все равно избавит вас от всех проблем управления потоками.
Тут нужно учитывать две вещи.
1. Сколько времени займет обработка записи?
Если обработка записей происходит очень быстро, накладные расходы на передачу записей потокам могут стать узким местом. В этом случае вы хотели бы иметь записи bundle, чтобы вам не приходилось передавать их так часто.
Если обработка записей достаточно длительна, разница будет незначительной, поэтому более простой подход (1 запись на поток), вероятно, является лучшим.
2. Сколько потоков вы планируете запустить?
Если вы не используете threadpool, я думаю, что вам нужно либо вручную ограничить количество потоков, либо разбить данные на большие куски. Запуск нового потока для каждой записи приведет к тому, что ваша система будет трястись, если количество записей станет большим.
Компьютер, на котором работает программа, вероятно, не является узким местом, поэтому: Помните, что протокол HTTP имеет заголовок keep-alive, который позволяет отправлять несколько запросов GET на одни и те же сокеты, что избавляет вас от рукопожатия TCP/IP. К сожалению, я не знаю, как использовать это в библиотеках .net. (Должно быть возможным.)
Вероятно, также будет задержка с ответом на ваши запросы. Вы можете попробовать убедиться, что у вас всегда есть заданное количество невыполненных запросов к серверу.
Получить параллельное Форекс . Посмотрите на BlockingCollection. Используйте поток для подачи в него пакетов записей, а также от 1 до n потоков, вытягивающих записи из коллекции в сервис. Вы можете управлять скоростью подачи коллекции и количеством потоков, вызывающих веб-службы. Сделайте его настраиваемым через ConfigSection и сделайте его универсальным, подавая делегаты действия сбора, и у вас будет хороший маленький дозатор, который вы можете использовать в свое удовольствие.