Recently we rewrote a working prototype library using structured programming techniques for maintainability. It accesses data from a third-party application (TPA) using the application's COM-based API. The API uses Win32 messaging (WM_COPYDATA) to communicate with TPA.
The new library code:
- Is written in C# with Visual Studio 2010 SP1.
- Targets .NET Framework 4 (was 3.5 in the prototype).
- Uses anonymous methods and new custom generic classes to factorise and simplify the original code, which does not use either (except for a few .NET Framework utility types like HashSet<>).
- References the COM-based API using unembedded interop types (Embed Interop Types=False) and registration-free COM (Isolated=True).
- Uses Marshal.ReleaseComObject for deterministic memory management with objects returned by the COM-based API.
- Uses the COM-based API only on a worker thread which runs in a single-threaded apartment (the COM-based API is apartment-threaded).
- Uses early binding when calling into the COM-based API.
Our tester application crashes randomly with AccessViolationException in the COM-based API. The stack trace shows that this occurs either in a call to UnsafeNativeMethods.DispatchMessageW (see sample below) or any of several different properties in the COM-based API. The tester application is a simple WinForms app with a menu, status bar and RichTextBox.
This behaviour is common to Windows XP and Windows 7, whether or not inter-thread communication between the worker thread and UI thread is enabled, whether or not we replace ReleaseComObject by FinalReleaseComObject. It seems to crash more frequently when TPA is very busy, eg. while it is starting up.
The prototype library was developed using VS 2008. After converting the project to VS 2010, the prototype application still does not crash.
System.AccessViolationException was unhandled Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt. Source=System.Windows.Forms StackTrace: at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.Run(Form mainForm) at IndexerTester.Program.Main() in D:\TestApps\Indexer\IndexerTester\Program.cs:line 17
Have you seen similar problems?
Can you offer any advice on isolating the cause and/or a potential workaround?