AccessViolationException возникает случайным образом в приложении .NET с использованием взаимодействия COM - PullRequest
0 голосов
/ 27 октября 2011

Недавно мы переписали работающую библиотеку прототипов, используя методы структурированного программирования для удобства сопровождения.Он получает доступ к данным из стороннего приложения (TPA) с помощью API-интерфейса приложения на основе COM.API использует обмен сообщениями Win32 (WM_COPYDATA) для связи с TPA.

Новый код библиотеки:

  1. Написан на C # с Visual Studio 2010 SP1.
  2. Цели.NET Framework 4 (в прототипе было 3.5).
  3. Использование анонимных методов и новых пользовательских универсальных классов для разложения и упрощения исходного кода, который также не используется (за исключением нескольких типов утилит .NET Framework, таких какHashSet <>).
  4. Ссылается на API-интерфейс на основе COM, используя встроенные типы взаимодействия (Embed Interop Types = False) и свободный от регистрации COM (Isolated = True).
  5. Использует Marshal.ReleaseComObject длядетерминированное управление памятью с объектами, возвращаемыми API-интерфейсом на основе COM.
  6. Использует API-интерфейс на основе COM только в рабочем потоке, который выполняется в однопотоковой квартире (API на основе COM является квартирным потоком).
  7. Использует раннее связывание при вызове API на основе COM.

Наше приложение-тестер случайным образом аварийно завершает работу с AccessViolationException iAPI на основе COM.Трассировка стека показывает, что это происходит либо при вызове UnsafeNativeMethods.DispatchMessageW (см. Пример ниже), либо в любом из нескольких различных свойств API на основе COM.Приложение-тестер представляет собой простое приложение WinForms с меню, строкой состояния и RichTextBox.

Такое поведение характерно для Windows XP и Windows 7, независимо от того, включена ли связь между потоками между рабочим потоком и потоком пользовательского интерфейса, заменяем ли мы ReleaseComObject на FinalReleaseComObject.Кажется, что происходит сбой чаще, когда TPA очень занят, например.во время запуска.

Библиотека прототипов была разработана с использованием VS 2008. После преобразования проекта в VS 2010 приложение-прототип по-прежнему не падает.

System.AccessViolationException isнеобработанное сообщение = попытка чтения или записи в защищенную память.Это часто указывает на то, что другая память повреждена.Source = System.Windows.Forms StackTrace: в System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW (MSG & msg) в System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoCoopMountMenceFidMenceFoundManagerManagerManagerManagerManagerManagerManagerManagerManagerManagerManagerManagerManagerManagerManagerManagerManagerManagerManager_Med_Med_Med_Med_M_W_P_M_P_M_P_M_P_M_P_M_P_M_P_C_M_P_M_P_C_M_P_C_P_M_P_C_F_M_P_C_Med_Med_Med_Med_MBпричина, Int32 pvLoopData) в System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner (причина Int32, контекст ApplicationContext) в System.Windows.Forms.Application.ThreadContext.RunMessageLoop (причина Int32, контекст ApplicationContext) в System.Windows.Forms.Application.Run (форма mainForm) в IndexerTester.Program.Main () в D: \ TestApps \ Indexer \ IndexerTester \ Program.cs: строка 17

Вы видели похожие проблемы?

Можете ли вы дать какие-либо рекомендации по выявлению причины и / или возможного обходного пути?

1 Ответ

0 голосов
/ 09 сентября 2016

Это немного поздно, но может кому-то помочь.

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

Мы заметили, что сбои происходили чаще, когда были заняты как стороннее приложение (TPA), так и наше приложение для тестирования (чтение данных из TPA).

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

...