• Как правильно построить обобщенное иерархическое выражение?

    @ProTreo
    DROP TABLE IF EXISTS #SalaryData
    CREATE TABLE #SalaryData (
      Id INT NOT NULL PRIMARY KEY IDENTITY,
      EmployeeId INT NOT NULL,
      SalaryDate DATETIME CONSTRAINT DF__SalaryData__SalaryDate DEFAULT (GETUTCDATE()),
      Salary DECIMAL(19,4) NOT NULL CONSTRAINT DF__SalaryData__Salary DEFAULT (0.0)
    )
    
    INSERT #SalaryData(EmployeeId, Salary)
    VALUES
    (2, 30000.0),
    (1, 40000.0),
    (5, 40000.0),
    (3, 30000.0),
    (4, 19000.0)
    
    -- Просто выборка по зарплате
    SELECT *
    FROM #SalaryData sd
    ORDER BY sd.Salary DESC
    
    -- Выборка зарплат и сотрудников, у которых зарплата больше чем у целевого сотрудника
    ;WITH CTE AS
    (
      SELECT
        RootEmployeeId = sd.EmployeeId,
        sd.EmployeeId,
        sd.Salary,
        Depth = 0
      FROM #SalaryData sd
    
      UNION ALL
    
      SELECT
        RootEmployeeId = cte.EmployeeId,
        sd.EmployeeId,
        sd.Salary,
        Depth = cte.Depth + 1
      FROM CTE cte
        INNER JOIN #SalaryData sd ON sd.Salary > cte.Salary
    )
    SELECT
      cte.RootEmployeeId,
      STRING_AGG(CONCAT(cte.Salary, '(', cte.EmployeeId, ')'), ',') WITHIN GROUP (ORDER BY cte.Salary ASC)
    FROM CTE cte
    WHERE cte.Depth < 2
    GROUP BY cte.RootEmployeeId
  • Как правильно построить обобщенное иерархическое выражение?

    @ProTreo
    Не очень понятно, на основе чего вы собираетесь строить иерархию(отношение parent - child) и какой смысл в использовании recursive cte в данном случае, когда можно обойтись простым запросом с order by
  • Почему отключается lan?

    @ProTreo
    В биосе иногда есть настройки связанные с энергоэффективностью сетевой платы, я бы там глянул + ну и вообще физическое соединение проверил бы
  • Вопросы по потокобезопасности коллекций и объектов?

    @ProTreo
    1.
    Наполнение коллекции должно будет происходить до операции чтения потоками.
    Если ваша коллекция будет уже сформирована и отсортирована, а также не будет меняться во время доступа из других потоков - вам не нужен никакой lock/mutex.
    Требуется ли для этого в момент чтения делать блокировку lock для обычного списка List?
    Нет
    Как можно решить данную задачу не используя lock и какая коллекция для этого подойдет?
    Следуя логике выше - любая коллекция, я бы проверял что выполнилось задание связанное с наполнением коллекции и только после этого разрешал бы делать сравнения.

    2.
    В пространстве Concurrent имеется список BlockingCollection.Он используется для безопасного добавления и чтения со встроенной блокировкой?
    Да, однако в вашем случае очень сильно ударим по перфомансу и вам совершенно не нужен, если вы собираетесь только читать информацию.

    3.
    Когда требуется чтение свойства объекта из множества потоков ссылочного типа или элементарного, то нужно ли делать блокировки? И нужно ли делать это в случае чтения потоками поля?
    Для чтения не надо.

    Если у вас будет происходить запись одновременно с чтением - нужен lock/mutex на доступ к полю/выполнение операции добавления/чтения из коллекции.
  • Почему "блокируется" второй поток при попытке http-request?

    @ProTreo
    Михаил, Еще может быть момент с тем, что у вас не хранятся референсы на таймеры. Я когда выполнял ваш код - клал каждый таймер в лист.
  • Почему "блокируется" второй поток при попытке http-request?

    @ProTreo
    Предположение:

    TimerCallback при создании таймера создает поток в ThreadPool. А там по сути существует очередь для выполнения, которую вы забиваете. У вас попросту кончается место в ThreadPool, поэтому коллбэки начинают исполняться медленно друг за другом.

    Погуглив можно найти советы в стиле - Timeout.Infinite для двух последних параметров при создании Timer и использование Timer.Change с Timeout.Infinite непосредственно в колбэке самой последней строчкой - таким образом в вашем случае не создастся к примеру 100 заданий в очереди к ThreadPool на обращение к определенному ресурсу, а таймеры будут рестартовать после завершения.

    Сейчас у вас если до ресурса за 3 секунды не достучатся - колбэк не успевает выполнится и создается 2, 3 и 4... колбэки и так до бесконечности. Представьте что будет если какой-нибудь ресурс отвалится с 404 ошибкой к примеру, или вы будете слать много запросов и сервак зафорсит разрыв соединения с вами или же самый худший вариант :) Истощение портов(port exhaustion) на вашем компе, когда у вас все повиснет в FIN_WAIT2 или CLOSE_WAIT - у вас останутся висеть открытые сокеты и некуда будет получать ответ, короче тлен.

    Ограничивайте многопоточность, попробуйте увеличить минимальное кол-во потоков для ThreadPool через метод ThreadPool.SetMinThreads (но они таким образом всеравно кончатся), обрабатывайте ошибки доступа к ресурсам, чтобы программа не падала и не используйте ThreadPool. Меньше головной боли.
  • Как можно посмотреть локальный сайт на моем компе через телефон?

    @ProTreo
    Зайди в настройки роутера и узнай ip мобилы и локального компа

    Если ОС - винда и работает денвер на 127.0.0.1:80 я бы попробовал вот что:

    Узнал ip компа, выданные dhcp сервером, в данном случае роутером.
    К примеру ip компа 192.168.0.100

    Мобиле выдается ip из той же сетки, к примеру 192.168.0.101 - это не принципиально.

    На винде открываешь консоль от админа и вводишь туда вот это:
    netsh interface portproxy add v4tov4 listenaddress=192.168.0.100 listenport=80 connectaddress=127.0.0.1 connectport=80

    После этого на мобиле в браузере вводишь 192.168.0.100 и должен открыться сайт.

    По крайней мере тут ничего лишнего качать не нужно