Отслеживание - и правильное завершение - собственных и управляемых потоков в приложении Windows C # - C ++ / CLI - C ++ форм перед выходом - PullRequest
0 голосов
/ 20 июля 2010

Это продолжение от:

Отладка многопоточного решения C # - C ++ / CLI - C ++ в Visual Studio 2008: что это за потоки?

Пожалуйста, извините за формат, я только что повторил некоторые описания приложения здесь:

Я унаследовал проект, состоящий из трех уровней кода.Самый нижний уровень - это родной C ++, который взаимодействует с оборудованием.Это зрелый, стабильный и хорошо проверенный.Кодом промежуточного уровня является C ++ / CLI, который взаимодействует с кодом C # верхнего уровня, который содержит элементы пользовательского интерфейса и некоторые дополнительные функции.Этот код C # является неполным и был спешно в разработке: он часто дает сбой и не подходит для цели.Моя задача - отладить и завершить ее.

Я получил очень полезную информацию из последнего вопроса, который я задал - но теперь есть больше проблем!Моя проблема на данный момент заключается в том, что когда я вызываю Application.Exit () для закрытия пользовательского интерфейса и выхода из приложения, возникает исключение:

System.InvalidOperationException: Collection was modified; enumeration operation may not execute

Я понимаю, что это потому, что мне нужно убедиться, чтовсе мои потоки заканчиваются, прежде чем я вызываю Application.Exit () (или Application.ExitThread ()).Я пытался использовать MainForm.Close () как быстрое решение, пока я продолжаю исследовать, но это не облегчает проблему.

Я не хочу просто вызывать Thread.CurrentThread.Abort (), главным образом потому, чтонекоторые потоки берут свое начало в разделе C ++ кода через Boost :: Thread, и я точно не уверен, какие ресурсы я могу оставить в нежелательном состоянии (большая часть кода состоит из объектов для взаимодействия с оборудованием, таких как:последовательный порт - он не был реализован через RAII, так что я довольно осторожен с грубым форсированием).

То, что я хотел бы сделать, это определить, какие потоки что делают, и изящно завершить их перед выходом из приложения.Однако в VS 2008 трассировка стека - с активированной «Показать внешний код» - показывает только

[Native to managed transition]
[Managed to native transition]

, поэтому у меня все еще возникают проблемы с отслеживанием отдельных собственных потоков и, таким образом, выработкой наилучшего способа завершения.их.

Я пытался использовать Allinea DDTLite, который выглядел превосходно - но у меня были некоторые проблемы с установкой VS, и мне пришлось отключить плагины, поэтому это не было решением.

Подводя итог: каков наиболее эффективный способ обеспечить правильное завершение всех потоков - как управляемых, так и собственных - чтобы пользовательский интерфейс, а затем и все приложение могли корректно завершиться?

1 Ответ

1 голос
/ 20 июля 2010

То, что я хотел бы сделать, это определить, какие потоки что делают

Вы не можете сделать эту работу. Существуют способы перечисления потоков в процессе, например, управляемого свойства Process.Threads или собственного Thread32First / Next, но вы не получаете достаточно информации о потоках, чтобы знать, что они делают. И, безусловно, не закрывать их чисто. Еще более усложняется платформой .NET, использующей потоки для своих собственных целей, таких как поток отладчика и поток финализатора, а также несколько потоков потоков.

Вы можете грубо уничтожить эти потоки с помощью TerminateThread, хотя уничтожение потока финализатора немедленно приведет к сбою программы, но это ничем не отличается от грубого завершения процесса с помощью Environment.Exit (). С оговоркой, что ничего не убирается красиво. Однако Windows очистит большую часть осколков.

Обычно это не должно быть проблемой. Вы знаете, какие потоки вы запустили, также должен быть механизм, чтобы попросить их завершить работу. Обычно это делается сигналом о событии, которое проверяется в основном цикле потока. Ожидание на ручке потока подтверждает, что поток действительно завершился. После чего вы можете закрыть окна.

Но это, вероятно, не хватает сантехники, вам придется добавить это. Если текущий нативный код C ++ не имеет механизма, позволяющего позаботиться о закрытии потока, то у вас довольно большая проблема. Я предполагаю, что поддержание этого нативного кода C ++ является реальной проблемой. Возможно, вам придется нанять оружие, чтобы сделать это.

...