Как лучше всего синхронизировать потоки в C#?

Мне стало интересно какой из существующих методов синхронизации потоков лучше использовать и почему.

Для синхронизации потоков можно использовать конструкцию lock или же Monitor.Enter / Monitor.Exit, которые являются аналогом lock. Также находил рекомендацию, что всегда лучше использовать lock, потому что он более безопасен: при использовании Monitor можно забыть установить конец критической области (Monitor.Exit).

Кроме lock и Monitor также для синхронизации потоков можно использовать классы Mutex или Semaphor, но перед их использованием почитайте документацию о них, ведь они позволяю реализовать синхранизацию между нескольку процессами (программами).
Также есть рекомендация, поскольку использования Mutex и Semaphort использует больше ресурсов системы чем lock и Monitor при синхронизации потоков в одном процессе, то при синхронихации потоков в одном процессе вместо них рекомендуется использовать SemaphoreSlim.
Кроме всего для синхронизации потоков ещё можно использовать класс EventWaitHandler и два производных от него класса: AutoResetEvent и ManualResetEvent.

Выбирать как именно нужно синхронизировать потоки нужно в зависимости от ситуации!

Дополнительно: Semaphore and SemaphoreSlim