Во-первых, пока вы правильно синхронизируете доступ к PaintQueue, я чувствую, что в этой ситуации это было скорее случайным, чем дизайном. Если у вас есть другой код, обращающийся к PaintQueue в других потоках, у вас есть проблема.
Во-вторых, этот код не имеет смысла. Вы создаете новый поток, увеличиваете значение в этом потоке и ждете 1/10 секунды. Дело в том, что код, запускающий поток, ожидает завершения этого потока. Из-за этого вы просто ждете в потоке пользовательского интерфейса ничего.
Даже если вы поставите в очередь события SelectedIndexChange, вы не сможете предотвратить зависание своего приложения. Событие SelectedIndexChange будет запускаться каждый раз, когда вы выбираете элемент, и если пользователь выбирает 5000 элементов, вам нужно обработать все 5000 событий. Вы можете дать им окно (обрабатывать каждые n секунд или что угодно), но это довольно произвольно, и вы кладете пользователя на таймер, что плохо.
Что вы должны сделать, это не связать операцию с событием SelectedIndexChanged. Вместо этого попросите пользователя выбрать элементы, а затем попросить их выполнить какое-либо другое действие (например, нажать кнопку), которое будет работать с выбранными элементами.
Ваше приложение все равно будет зависать, если вам придется обрабатывать несколько элементов в течение длительного периода времени в потоке пользовательского интерфейса, но по крайней мере выбор элементов не будет зависать.