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
Не очень понятно, на основе чего вы собираетесь строить иерархию(отношение parent - child) и какой смысл в использовании recursive cte в данном случае, когда можно обойтись простым запросом с order by
1. Наполнение коллекции должно будет происходить до операции чтения потоками.
Если ваша коллекция будет уже сформирована и отсортирована, а также не будет меняться во время доступа из других потоков - вам не нужен никакой lock/mutex. Требуется ли для этого в момент чтения делать блокировку lock для обычного списка List?
Нет Как можно решить данную задачу не используя lock и какая коллекция для этого подойдет?
Следуя логике выше - любая коллекция, я бы проверял что выполнилось задание связанное с наполнением коллекции и только после этого разрешал бы делать сравнения.
2. В пространстве Concurrent имеется список BlockingCollection.Он используется для безопасного добавления и чтения со встроенной блокировкой?
Да, однако в вашем случае очень сильно ударим по перфомансу и вам совершенно не нужен, если вы собираетесь только читать информацию.
3. Когда требуется чтение свойства объекта из множества потоков ссылочного типа или элементарного, то нужно ли делать блокировки? И нужно ли делать это в случае чтения потоками поля?
Для чтения не надо.
Если у вас будет происходить запись одновременно с чтением - нужен lock/mutex на доступ к полю/выполнение операции добавления/чтения из коллекции.
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. Меньше головной боли.
Зайди в настройки роутера и узнай 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 и должен открыться сайт.
По крайней мере тут ничего лишнего качать не нужно