yurabrg: В скайпе могу разве что поздно вечером. Вы правильно думаете, но в данном случае боль вам создает ThreadPool используемый в Task.Run, он ждет когда вернется управление из метода, а оно не вернется до тех пор, пока лямбда не доработает до конца, тут ваша идея и ломается. Когда вы используете async/await, вам не нужно это заворачивать в отдельные потоки, реализации асинхронных методов сами позаботятся о том как выполнять свой код асинхронно.
yurabrg: Вы запускаете множество отдельных методов, которые сначала помещаются в очередь и обрабатываются малым кол-вом потоков (их всё равно ограничит система), потоки еще требуют переключение контекста, пусть не так тяжело как процессы, но всё же.
По поводу почему await так отработает, посмотрите какой IL код будет сформирован, по await будет разбит на отдельные методы, которые вызываются последовательно, но проблема в том, что задача в очереди не будет считаться законченной, пока не завершится ваша лямбда. А т.к. в лямбде обрабатывается один запрос и все операции строго последовательны, вы и получите обычное синхронное выполнение. Если вы откажетесь от асинхронных методов, никакой разницы не будет, ваш код будет работать точно так же как и с асинхронными методами. И всё потому, что обёртками вы их выстраиваете в цепочку, вы сами же не даётё выполнятся одновременно HTTP запросам.
yurabrg: На деле если вы уберете Task.Run, то скорее всего заработает всё куда как быстрее, а точнее, вы уберете лямбду (если всё будет в теле одного метода), в этом случае await сделает что-то похожее на использование BeginGetResponse и вызов делегата по окончании web запроса.
yurabrg: ну в вашем случае await скорее всего превратит вызов последнего метода в синхронный, а т.к. для работы потребуется еще и результат предыдущего вызова с await, то получается, что всё отработает без какой-либо асинхронности, у вас зависимые друг от друга операции в единственном экземпляре.
Правильнее было бы в цикле вызвать BeginGetResponse, по окончании запроса будет вызван делегат с результатом и всё, никаких потоков вообще и всё быстро и асинхронно.
Не знаю сколько реально потоков будет использовать Task.Run, но вряд ли это большое значение, да и запускать на каждый запрос отдельный поток тоже глупо, особенно когда есть возможность обойтись даже одним потоком. Ваши потоки будут просто висеть и ждать пока придут данные. Если к примеру кол-во потоков будет равно кол-ву ядер процессора, то о чём-то эффективном речи вообще не идёт.
Ну готовых примеров использование пользовательских аттрибутов в C# много. Да и я не говорил, что if плох, просто аттрибуты позволяют удобнее структурировать код, разносить этот самый код по отдельным файлам. if же должны быть сосредоточены в одном месте, да и на деле с аттрибутами if никуда не пропадут, просто информацию для сравнения будут брать из аттрибутов. Поковыряйте https://msdn.microsoft.com/en-us/library/930b76w0.aspx тут и рассказано, как это можно сделать на C# с использованием аттрибутов.
А вы как-то иначе хотите? Убить поток вместо нормального завершения по вашему нормальное поведение? Вы же не выходите из функций в случае нормального завершения бросая исключение.
И в чём проблема? Или вы не хотите использовать правильный механизм предназначенный для задачи именно потому, что вам не хочется проверять флаг? Или в треде while с проверкой нормально, а вот в BackgroundWorker нет?
MoreBeauty: Ну count видимо определяется свойством Count, тут понадобится реализовать свою коллекцию видимо. А вот с деревом естественно будет сложнее. Либо делать nested-tree и в самой коллекции еще отслеживать раскрытость/закрытость веток, либо подтягивать полностью 1 уровень раскрытой ветки не задумываясь о кол-ве отображаемых элементов.
Ну так и не тяните все, вам для полосы прокрутки достаточно только информации о кол-ве. А данные подтягивайте по мере надобности, конечно реализация будет чутка посложнее, но и так возможно. Или возьмите DataGrid.
Очень элементарно используется. Например книга "C# 5.0 и платформа .NET 4.5" К. Нейгел, Б. Ивьен, Д. Глинн, К. Уотсон, М. Скиннер. Там раскрыта тема MEF.
А что, прикольно, человек получает зарплату, что работает ведущим разработчиком/начальником отдела или что-то в этом роде, но при этом не знает что требуется сотрудникам на данной должности. Я бы на месте вашего работодателя вас уволил. А учитывая, что Junior это не полноценный разработчик, а только ученик, то и должен делать какую-нить фигню, но никак не сервера.
MoreBeauty: Ну ваша первая ошибка, это создание своего делегата. А на деле есть Generic делегаты (Action и Func), которые и рекомендуется использовать. Так что берите нормальную книгу и читайте. С Рихтера наверное правда начинать не стоит.