Вы правы. Код не является потокобезопасным. Но не по той причине, вы думаете.
AutoResetEvent в порядке. Но только потому, что вы приобрели блокировку и повторно протестировали PendingOrders.Count. Суть в том, что вы вызываете PendingOrders.Count за пределами блокировки. Поскольку класс Queue не является потокобезопасным, ваш код не является потокобезопасным ... точка.
Теперь в действительности у вас, вероятно, никогда не будет проблем с этим по двум причинам. Во-первых, свойство Queue.Count почти наверняка разработано так, чтобы никогда не оставлять объект в полусгоревшем состоянии. В конце концов, он, вероятно, просто вернет переменную экземпляра. Во-вторых, отсутствие барьера памяти для этого чтения не окажет существенного влияния в более широком контексте вашего кода. Худшее, что может случиться, это то, что вы получите устаревшее чтение на одной итерации цикла, а затем полученная блокировка неявно создаст барьер памяти, и на следующей итерации будет выполнено новое чтение. Я предполагаю здесь, что есть только один поток элементов очереди. Вещи значительно меняются, если их 2 или более.
Однако позвольте мне сделать это совершенно ясно. У вас нет гарантии, что PendingOrders.Count не изменит состояние объекта во время его выполнения . И поскольку он не заключен в блокировку, другой поток может инициировать на нем операцию, пока он еще находится в этом полуобеспеченном состоянии.