Как стать автором
Обновить
236
0
Сергей Тепляков @SergeyT

Пользователь

Отправить сообщение
Одной из идей статьи является проектирование; выбор того или иного решения в контексте конкретной задачи, вот и запостил в «Проектирование и рефакторинг». Если есть идеи, где это дело будет уместнее опубликовать: велкам! С радостью перенесу.
Да, нормальные стабы всегда предпочтительнее молов, но стабы не позволят отвязаться от внешнего environment-а, а вот с этим молы как раз справляются на ура.
Капитан, благодарю! Но я правда только сейчас нашел использование поля Index. Оно есть только NewASyncDownload, хотя этот класс используется во всех методах.
2. Rx — ставится отдельно, а PFX входит в состав .net 4.0
3. Понял, но я бы выделил его тогда, когда появится в нем необходимость.
4. Не понял:)
5. Ок
6. Ок

Блин, почему здесь нет смайлов, аналогичных rsdn-овским, вот с таким общением, явно нужен смайл :bear:!
Букав просто дофига! Не факт, что все понял и осилил, но пару замечаний есть.

1. Я вообще не въехал, что за UrlExt, поскольку я нигде не увидел использование поля Index этого класса.
2. RxASyncDownload никакого отношения к RX не имеет. Там есть PFX, но нет Rx-a (вот тут я писал про rx, глянь последний пример плз). Здесь мы стартанем такое количество задач параллельно, сколько у нас ядер (кажись именно такое поведение по умолчанию в PFX) и здесь, кстати, оно ни к чему, поскольку Parallel.For призвано прежде всего для распараллеливания CPU-bound операций, а у нас здесь IO-bound, так что нам здесь нет смысла ограничиваться количеством параллельных операций, равному количеству ядер процессора (ну, логическому количество процессоров).
3. ИМХО, нет смысла выделять отдельный метод DoASyncDownloadV1, поскольку он не самостоятелен и все время приходится смотреть, что же он такое делает.
4. Не увидел разницы между NewASyncDownload и NewASyncDownloadV2. В первом случае перебор всех урлов производится с помощью LINQ, а во втором случае — с помощью простого цикла. При этом для NewASyncDownloadV2 введено целых два вспомогательных метода, которые нужно анализировать, чтобы понять, что там происходит. Опять ИМХО, это личшее.
5. NewASyncDownloadV3 мне практически вывихнул мозг, поскольку там аж четыре метода. Зачем-то используется List output, который передается другому методу, который изменяет значение по нулевому индексу, и потом это же значение (из нулевого индекса) возвращается из метода DoASyncDownloadV3. И, как я понял, все это для того, чтобы выполнить все эти операции асинхронно, но начинать каждую следующую по завершению предыдущей асинхронной операции.
По сути, это то, что привел в самом первом примере, когда в синхронную версию добавил модификаторов async и await.
6. NewASyncDownloadV4 и я опять не понял в чем смысл? Зачем использовать PFX, когда мы можем просто начать последовательно несколько асинхронных операций и потом уже ждать их завершения? Я например, не знаю, как будет параллелиться этот код:) Вы знаете, сколько операций будет запущено асинхронно одновременно на моем (именно моем) компьютере? Опять повторюсь, Parallel.For — это для параллельных вычислений, а не для параллельного ввода-вывода.

З.Ы. Написано очень много букв и многие из них вполне разумны. Единственное, на что я хочу обратить внимание, так это на то, что разбивать все на методы, которые не самостоятельны не всегда хорошо. Проще, чтобы было сразу же в одном методе видно, что есть что.
А так, молодца!!!
Но ведь мы не об этом коде говорим;) Приведенный код — это упрощение синхронной версии, а не асинхронной. Подобный код для асинхронной версии только усложнит код.

Кроме того, вы задумывались зачем вообще ввели все эти анонимные делегаты и лямбды? На самом деле, далеко не всегда следует выделять некоторую логику в отдельный метод. Например, в некоторых случаях некоторая логика неотъемлемо связана с другой логикой; она не самостоятельно. Тогда в этом случае выделение отдельного метода лишь уменьшает связанность (cohesion), и мы получаем, что одна, по сути, логика начинает «расползаться» по нескольким методам. Тогда, вместо того, чтобы взять и прочитать все в одном месте, нам нажно шариться по трем десяткам функциям, каждая из которых сама по себе ни имеет ни малейшей ценности. Именно в этих случаях повышение декларативности (с помощью того же линка) начинает играть положительную роль.

З.Ы. Анонимные типы с var-ом не имеет ничего общего (да, анонимные типы без var-ов никуда, но это не единственный кейс применения этого ключевого слова). Но фраза «анонимный тип var» — это не корректная фраза.
Т.е. мы хотим выяснитиь в чем разница между простым вызовом синхронного метода, т.е. SyncVersion() и вызовом его через Thread Pool (например): ThreadPool.QueueUserWorkItem(o=>SyncVersion());?
Здесь нет разницы, поскольку мы как выполняли этот метод 10 секунд, так и выполняем, мы просто отвязали поток выполнения, от пока, который его инициировал. Я уже писал в комментариях, что главная выгода от асинхронных операций состоит не в этом. Главная выгода состоит в том, что мы можем повысить не только *отзывчивость* пользовательского интерфейса (что более или просто), а повысить эффективность, за счет того, что мы начнем несколько асинхронных операций *одновременно*. В этом случае мы уменьшим время выполнения, например, с 15, до 5 секунд.

Там же по ссылке вроде бы это описано, да и в комментах об этом уже написано;)
Вот блин, я никогда себя фанатом LINQ-а не считал:) А где я тут им злоупотребил? Он может быть непривычен, это да, но читать (если привыкнуть) станет легче. А тут я создаю анонимный тип, который связывает URL и ответ, чтобы когда я буду итерировать ответ не нужно было по индексу обращаться в другую коллекцию, а все было сразу под рукой.
Он же читается практически так же как пишется:
взять url из urls
создать WebRequest
сделать анонимный класс с парой полей: URL и web response-ом на этот url
дернуть ToList, поскольку без него ленивая природа LINQ-а сделает свое грязное дело в результате чего асинхронные запросы будут выполняться по одному, что прибьет основную от них выгоду.

Вроде бы, опять же, не матан:)
Вся выгода от *одновременного* выполнения нескольких асинхронных операций. Этим кодом я пытался показать, что у нас три асинхронные операции, а то, что они однотипные — это не важно, ну, просто так получилось.
Точнее, it depends. Если вы запустите подобную операцию в обработке кнопки мыши, то никаких дополнительных потоков не будет, а если в консоли — то будут (см. вывод первого примера).
Может быть в первом посте из этой серии будет более понятна идея, поскольку здесь всего-лишь асинхронится то, что рассказывалось там, только третьим способом.
Но, в любом случае пример (который в этой статье и приведен) показывает следующее: нам выгоднее запустить 3 асинхронные операции получения веб-респонса *одновременно*, а не последовательно, поскольку в этом случае результат мы получим тупо быстрее (причем почти в трое), поскольку большую часть времени выполнения этой операции мы просто ждем ответа от сети. И это далеко не одно и тоже, что мы их запустим в другом потоке с помощью пула потоков, поскольку в этом случае выгоды мы вообще не получим. По сути, именно это мы видим в самом «наивном» использовании новой асинхронности: мы по-сути выгоды не получаем, мы просто выполняем все операции асинхронно, возможно даже не используя новые потоки (если запустить эту функцию в обработчике клика мыши, то отзывчивость приложения будет в три раза выше). Выгоду мы получаем только в самом последнем примере, когда все три запроса делаются *параллельно*, что и показано в последнем примере.
Отсутствие привязки к одному ЯП — это очень здорово и правильно и как уже писали в комментариях те же Хант и Томас (а не Спольски) советуют изучать по одному ЯП в год, причем не обязательно в промышленном использовании, а хотя бы для ознакомления с концепциями и «перекрессного опыления» идей.

Но вот слово «выучить» нельзя (ну или по крайней мере опрометчиво) применять как к естественным языкам, так и языкам программирования. Спросите у любого лингвиста знает ли он соответствующий язык? Он едва ли ответит вам «да, я его знаю» и тем более он не даст вам ответа на вопрос, «а как выучить английский?».

То же самое справедливо и для ЯП. Небезысвестный Эрик Липперт в одной из своих последних заметок отлично процитировал Питера Норвига о том, что серия книг «ЯП за 21 день» на самом деле должна называться так: Teach Yourself Programming In Ten Thousand Hours Because Realistically That Is About How Long It Takes To Gain Expertise At Any Skill.

Кстати, с этим согласен и Хант в своей книге Refactor Thinking and Learning, где он упоминает о том, что для того, чтобы стать профессионалом в среднем требуется не менее 10 лет.

З.Ы. Я согласен, что ставить ЯП во главу угла глупо и что понятие «программировать с использованием языка», а не «на языке», введенное Макконнеллом очень разумно и полезно, но, нужно отметить, что с изучением чего-либо и ЯП в частности все не так просто;)
Более того, для вменяемой отладки нужно несколько способов запуска приложения: один — запуск в виде сервиса, двугой — в виде стандартного консольного приложения, в котором вся отладка прекрасно работает. Запустил приложение без ключа — стандартное консольное приложение, запустил с ключом /service — сервис.
Я недавно заказывал с амазона, доставка выходила около 8$, что в общем-то не очень-то и много. Да вы еще и учтите, что если купите штуки три не толстые книги, то стоимость доставки практически не изменится и в сумме выйдет совсем не много.
Да я-то понимаю, что стоимость издания (точнее как минимум сложность перевода) у такой книги очень прилична, а возможная выгода не очевидна, вот сейчас и не берется практически никто за переводы «толстых» книг, а у Мейера еще и терминология дурная, согласовать ее с общепринятой не так-то просто.
Рихтера, вроде бы кто-то сейчас переводит (скорее всего Питер, ведь именно они издавали предыдущее издание). Я предлагал издательству Символ-Плюс перевести C# In Depth, но так и не понял чем дело закончилось.
Может маленький флеш-моб даст понять, что эта книга актуальна…
У меня все книги истыканы закладками и почерканы, так что я пока не знаю, как бы мне в этом мог помочь e-book. Но если у вас есть идеи по этому поводу — готов прислушаться;)
Я Эрика с огромным трудом догнал, да и редактирование книг занимает прорву времени:) Другие блоги — мало вероятно, а вот перевести старые классные посты Эрика — вот это запросто (я ведь именно из-за этого и создал этот пост;) )
Если вы про новые посты, то проще подписаться на RSS этого блога да и все (поскольку я не собираюсь бросать это дело)… А если вы о других блогах… то даже не знаю… :)))

Информация

В рейтинге
Не участвует
Откуда
Washington, США
Зарегистрирован
Активность