2010-11-12 6 views
2

Я работаю над небольшим приложением, которое предназначено для вызова некоторых (очень разнообразных) функций, которые, к сожалению, находятся вне моего контроля и разработаны таким образом, что я понятия не имею, пользователь действие сделан. В частности, некоторые из них порождают поток для выполнения своей работы, который в конечном итоге заканчивается в какой-то момент в будущем. Итак, некоторые из них реализованы в синхронизации, некоторые из них реализованы асинхронно, а мой код не знает, какой из них он будет.COM-функции порождают потоки, которые не исчезают

только Цель моей заявки - запустить эти задачи и завершить работу по завершении. Поскольку цель - автоматизация, я ожидаю, что она будет вызвана в 100 раз из пакетных файлов в считанные минуты, поэтому я не хочу, чтобы процесс задерживался дольше, чем это было возможно.

Поскольку у меня нет никакого сигнала, я могу подождать, ExitThread() на моей основной теме, кажется, путь, так что любые потоки, порожденные внешним кодом, будут убивать процесс, когда они завершатся.

Итак, чтобы перейти к моей фактической проблеме, упомянутой в названии. :) Чтобы получить правильные интерфейсы для моего jig, мне нужно возиться с некоторыми функциями COM. SHParseDisplayName, IShellFolder::GetUIObjectOf и кучу других. Но уже после того, как я закончил с этими интерфейсами и выпустил их, эти потоки остаются присутствующими. Даже после того, как я позвонил CoUninitialize().

При проверке моего процесса с использованием Process Explorer большинство этих потоков, похоже, имеют [email protected] в качестве точки входа и застревают в ntdll.dll!ZwAlpcSendWaitReceivePort+0xa. Очевидно, что случайное завершение потоков с использованием TerminateThread здесь не является вариантом.

Как я могу заставить COM прекратить эти потоки, когда я закончил использовать его? Я использую W7 x64 для разработки.

ответ

0

Я выяснил проблему, и это был очевидный случай, когда вся документация была где-то, а не там, где вы смотрите, а у некоторой родственной темы был blog post по этой проблеме, которая привела меня к недостающему фрагменту.

Мое приложение всплывает IContextMenu файла (отсюда нет ShellExecute в моем коде), а затем позволяет вызвать команду. Однако некоторые глаголы, такие как properties, - это странные вещи, о которых я спрашивал: они порождают еще один поток и не дают никакого уведомления или очевидного способа его блокировки.

Использование SHSetExplorerInstance, как упоминалось в связанном посте, исправил мои проблемы. :)

4

Эти потоки не принадлежат COM. Они принадлежат к собственному пулу потоков Windows. Они предназначены для того, чтобы придерживаться, чтобы их можно было повторно использовать при необходимости. Предполагая, что нет ожидающих асинхронных обратных вызовов, вы должны иметь возможность отключить их. Пул потоков позаботится о том, чтобы быстро уничтожить потоки.

+0

Странно, не получил уведомление, на которое вы ответили. В любом случае, моя «основная» нить мертва, поток, который он намеренно породил, мертв, и все же у меня остался мертвый процесс с кучей нитей, в которые я не могу повлиять. Боюсь, я не вижу никаких следов их уничтожения. – Stigma

+0

Возможно, у вас есть ошибка подсчета ссылок интерфейса COM или что-то еще, что держится за ресурсы. В любом случае, если вы используете C Runtime, он должен завершить процесс, как только ваш основной поток вернется с основного или wWinMain (независимо от того, какие другие потоки могут выполняться). Он делает это, вызывая функцию выхода. Если вы не используете C Runtime, вы можете вызвать функцию ExitProcess для достижения той же цели. –

+0

Я знаю все это. Вы прочитали вопрос? В нем точно сказано, почему я не могу зависеть от ExitProcess и хочу, если возможно, переключиться на ExitThread().- Что касается подсчета ссылок. Я прошел через код, следя за тем, как создаются неприятные потоки, но интерфейсы, участвующие в рассматриваемых командах, выпущены несколькими строками позже. – Stigma

Смежные вопросы