Я хотел бы продвигать Common Table Expressions для этого:
WITH selector_heat as (
SELECT
box_score.team_name,
ROUND(AVG(eFG),3) eFG,
ROUND(AVG(OPP_eFG),3) OPP_eFG,
ROUND(AVG(TOV_PCT),3) TOV_PCT,
ROUND(AVG(OPP_TOV_PCT),3) OPP_TOV_PCT,
ROUND(AVG(ORB_PCT),3) ORB_PCT,
ROUND(AVG(DRB_PCT),3) DRB_PCT,
ROUND(AVG(FTA_RATE),3) FTA_RATE,
ROUND(AVG(OPP_FTA_RATE),3) OPP_FTA_RATE
FROM box_score
WHERE team_name = 'Miami Heat' AND WIN_LOSS = 'W' AND game_date < '2019-03-07'
)
, selector_knicks as (
...
)
select H.eFG - K.OPP_eFG as magic_nbr
from selector_heat H
join selector_knicks K ON (1=1)
Подробнее о синтаксисе здесь: https://www.sqlite.org/lang_with.html , но пока игнорируйте «рекурсивные» биты, они вам не нужны этот экземпляр.
В качестве альтернативы (и с немного другим углом подхода) вы можете использовать предложения Window для агрегирования «на команду», а затем использовать результаты. Более подробная информация здесь: https://www.sqlite.org/windowfunctions.html#introduction_to_window_functions
Пример:
SELECT
team_name,
WIN_LOSS,
ROUND(AVG(eFG) OVER (partition by team_name, win_loss),3) as eFG
...
from box_score
where game_date < '2019-03-07'
С этим набором результатов у вас есть свои средние значения для все команды и комбинации win_loss. Оберните это в CTE и присоедините к себе на подходящих условиях, например
WITH cte as (SELECT ...)
SELECT H.eFG - K.OPP_eFG as magic_nbr
FROM cte H join cte K
ON (H.team_name = 'Miami Heat'
AND K.team_name = 'NY Knicks'
AND H.win_loss = 'W'
AND K.win_loss = 'L')
То Взаимное исключение (потому что это имеет имя) остановит любой процесс на той же машине, получающей доступ к нему также, тогда как блокировка только остановит другие потоки в том же процессе. Я не вижу из того примера кода, почему Вам были бы нужны оба вида блокировки. Это кажется хорошей практикой для содержания простой блокировки в течение короткого промежутка времени - но затем намного более тяжелое межпроцессное взаимное исключение заблокировано для, вероятно, дольше (хотя наложившись) период! Было бы более просто просто использовать взаимное исключение. И возможно узнать, действительно ли межпроцессная блокировка необходима.
Между прочим, catch {}
абсолютно неправильная вещь использовать в том сценарии. Необходимо использовать finally { /* release mutex */ }
. Они очень отличаются. Выгода будет глотать намного больше видов исключения, чем это должно, и также заставлять вложенный наконец обработчики выполняться в ответ на исключения низкого уровня, такие как повреждение памяти, нарушение прав доступа, и т.д. Так вместо:
try
{
// something
}
catch
{}
// cleanup
Вы должны иметь:
try
{
// something
}
finally
{
// cleanup
}
И если существуют определенные исключения, можно восстановиться с, Вы могли бы поймать их:
try
{
// something
}
catch (DatabaseConfigurationError x)
{
// tell the user to configure the database properly
}
finally
{
// cleanup
}
"блокировка" является в основном просто синтаксическим сахаром для Montor. Ввести/Выйти. Взаимное исключение является блокировкой мультипроцесса.
У них есть совсем другое поведение. Нет ничего неправильно с использованием обоих в том же приложении или методах, так как они разработаны для блокирования разных вещей.
Однако в Вашем случае, я думаю, что можно быть более обеспеченным изучением Семафора и Монитора. Это не кажется, что необходимо заблокировать через процессы, таким образом, они - вероятно, лучший выбор в этой ситуации.
Как другие указали, Взаимоисключающие блокировки через процессы и локальная блокировка (Монитор) блокирует только те потоки, принадлежавшие текущему процессу. Однако...
Код, который Вы показали, имеет довольно серьезную ошибку. Похоже на выпуск Взаимного исключения безусловно в конце (т.е. reconnectMutex.ReleaseMutex()
), но Взаимное исключение только получено если site.ContainsKey()
возвраты true
.
Итак, если site.ContainsKey
возвраты false
, затем выпуск Взаимного исключения собирается бросить ApplicationException
потому что вызывающий поток не владеет Взаимным исключением.
Вы не дали достаточно информации для реального ответа на это. Как уже указано Earwicker Взаимное исключение позволяет Вам иметь синхронизацию через процессы. Таким образом, если у Вас есть два экземпляра того же приложения, выполняющего Вас, может сериализировать доступ. Вы могли бы сделать это, например, при использовании внешних ресурсов.
Теперь Вы соединяетесь, сайт защищает сайт от доступа другими потоками в том же процессе. Это могло бы быть nessecary в зависимости от того, что другие методы / делают потоки. Теперь, если это - единственное место, что сайт блокируется затем да, я думал бы, что это - излишество.