Multiple thread problem in VSTA

Q:

 

Here is a question about VSTA multi threads. I have a function to create a new project file. It works fine when I just run the line of code in VSTA. But it failed when debugging. I looked into it and found no difference except for the executing thread.

When I run the macro, the main thread calls into the function, while a worker thread runs into it when I debug into it.

When I run the macro, it is executed by the main thread.

When I debug, it is executed by a worker thread.

I suspect this causes the function to fail. Any ideas?

Here is the exception I got:

Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

 

 

A:

 

This change in behavior (Main thread vs. worker thread) occurs because System.AddIn’s AddInProcess is used to execute the add-in in an external process for out-of-process debugging.  AddInProcess design uses an Inter-Process Communication channel, which causes the add-in to execute on an MTA thread.  Add-in execution on a MTA thread causes problems with add-in UI -- the UI’s messaging must run on a STA thread.

 

If are debugging into MFCDocTEmplate::Open, that is very likely interacting with your host application’s UI thread.  Please see the ShapeAppMacroRecording SDK sample’s approach to this problem.  The sample takes pains to properly manage cross-thread UI interaction.  Here’s one example of it from the sample – note the code section beginning with:  if (form.InvokeRequired) // Make sure it's safe to be called on another thread.

==               

        public Drawing ActiveDrawing

        {

            get

            {

                Drawing activeDrawing = null;

                if (form.InvokeRequired) // Make sure it's safe to be called on another thread.

                {

                    form.Invoke(

                        (Action)(() =>

                        {

                            if (form.drawingsTabControl.SelectedTab != null)

                                activeDrawing = form.drawingsTabControl.SelectedTab.Tag as Drawing;

                        }));

                }

                else

                {

                    if (form.drawingsTabControl.SelectedTab != null)

                        activeDrawing = form.drawingsTabControl.SelectedTab.Tag as Drawing;

                }

                return activeDrawing;

            }

        }

 

 


Posted Jun 08 2009, 08:31 AM by BillL
Filed under: , , ,
Copyright Summit Software Company, 2008. All rights reserved.