Здравствуйте, Odi$$ey, Вы писали:
OE>да, надо
S>>см есть пример в msdn. Если последовательность сложная, возможно будет удобнее навернуть то же самое через Rx.
OE>глянул, попробую из интереса прикрутить к своему примеру, но что-то по-моему это посложнее будет чем Dns.BeginGetHostEntry/EndGetHostEntry Непонятно всё как-то с этим async/await, в простых случаях это не надо, т.к. и так все просто, а в реальном случае всё только сложнее получается...
Здравствуйте, Odi$$ey, Вы писали:
OE>Непонятная разница в количестве используемых потоков для кода с await/async и для голой Dns.BeginGetHostEntry/EndGetHostEntry. OE>Вопрос — как порулить количеством потоков для await/async (Task)?
А у вас точно все задачи запущены _до_ первого await?
Иначе получается последовательность "запускаем задачу, продолжаем после её завершения, запускаем следующую ..." и по времени выполнения код несильно будет отличаться от однопоточного.
Здравствуйте, Odi$$ey, Вы писали:
OE>Вопрос — как порулить количеством потоков для await/async (Task)?
Надо только не забывать про используемый шедулер. в GUI приложении поток может оказаться вообще один.
В любом случае, потоки могут быть нужны только в случае если обработка GetHostEntryCallback занимает продолжительное время.
Если это просто печать на экран то, вполне можно обходиться и одним потоком.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Непонятная разница в количестве используемых потоков для кода с await/async и для голой Dns.BeginGetHostEntry/EndGetHostEntry.
Если я вызываю в цикле для некоторого дипазона IP адресов
Dns.BeginGetHostEntry(adr, new AsyncCallback(GetHostEntryCallback), adr);
и потом ловлю результаты в GetHostEntryCallback(IAsyncResult ar), то результат примерно такой (в квдратных скобках [] — идентификаторы потоков):
15:38:03 [ 1]: Начинаем сканирование...
15:38:03 [ 3]: 192.168.4.120 pc
15:38:03 [ 4]: 192.168.4.121 ak
15:38:03 [ 3]: 192.168.4.122 va
15:38:03 [ 4]: 192.168.4.123 mo
15:38:03 [ 3]: 192.168.4.124 pi
15:38:03 [ 4]: 192.168.4.125 cr
15:38:03 [ 4]: 192.168.4.127 se
15:38:04 [ 5]: 192.168.4.129 eg
15:38:05 [ 7]: 192.168.4.132 sh
15:38:06 [ 9]: 192.168.4.135 va
15:38:12 [ 3]: 192.168.4.126 Этот хост неизвестен
15:38:12 [ 4]: 192.168.4.128 Этот хост неизвестен
15:38:13 [ 5]: 192.168.4.130 Этот хост неизвестен
15:38:13 [ 6]: 192.168.4.131 Этот хост неизвестен
15:38:14 [ 7]: 192.168.4.133 Этот хост неизвестен
15:38:15 [ 8]: 192.168.4.134 Этот хост неизвестен
15:38:15 [ 1]: Нажмите Enter для завершения...
всего 8 потоков, 12 сек, операции для отсутствующих ip, самые длительные, висят одновременно. Причем количество потоков можно увеличить еще больше (и сократить время) если задать например ThreadPool.SetMinThreads(50, 50);
// Запускаем задачиvar tasks = ipAdresses.Select(a=>Dns.GetHostEntryAsync(a)).ToArray();
// Дожидаемся, пока все не отработают.
await Task.WhenAll(tasks);
foreach (var task in tasks)
{
var data = await task; // Ну, или task.Result, после завершения WhenAll() все задачи уже выполнятся.
}
Если нужно обрабатывать результаты по мере поступления, см есть пример в msdn. Если последовательность сложная, возможно будет удобнее навернуть то же самое через Rx.
Здравствуйте, Sinix, Вы писали:
S>Если нужно обрабатывать результаты по мере поступления,
да, надо
S>см есть пример в msdn. Если последовательность сложная, возможно будет удобнее навернуть то же самое через Rx.
глянул, попробую из интереса прикрутить к своему примеру, но что-то по-моему это посложнее будет чем Dns.BeginGetHostEntry/EndGetHostEntry Непонятно всё как-то с этим async/await, в простых случаях это не надо, т.к. и так все просто, а в реальном случае всё только сложнее получается...