Hang-ups during in-process debugging.

 

Here is Microsoft’s workaround for the problem hang-ups during in-process debugging:

“The idea is that we want to wait for the type –registering threads to finish before we call addin.FinishInitialization.

What I did is to record the number of threads in the process before we activate add-in. After addin.Initialize (when the type-registering happens), I’ll track the thread number going up and down. When the thread number is exactly 1 + pre-addin-load number, I know the type registering is done. The workaround kicks in only during debugging. With the workaround, the problem goes away as I tried (note some time you may need to wait a while, as long as several seconds, for the break point to hit.)…”

 

        private IEntryPoint LoadAddIn(string addInPath, string startUpClass, AddInProcess addInProcess)

        {

            try

            {

                //Start Workaround for AddIn_Startup debug hanging problem

                // Used to keep track the type registering threads.

                int threadCountBeforeLoadingAddIn = Process.GetCurrentProcess().Threads.Count;

                // End Workaround

 

                // Search for the AddIn at the given location and make sure that it has

                // the same Startup class. Also make sure that we can load this Addin

                // using the default VSTA pipeline. This function will return a token

                // to the AddIn which can be later on used to actually load the AddIn.

                Collection<AddInToken> addInToken = AddInStore.FindAddIn(typeof(IEntryPoint), AddInStoreExtensions.DefaultPipelinePath, addInPath, startUpClass);

 

                // Assert the AddIn is valid.

                System.Diagnostics.Debug.Assert(addInToken.Count >= 1);

 

                // If the AddIn is not valid then return false.

                if (addInToken.Count == 0)

                    return null;

                IEntryPoint addIn = null;

                // Using the Token returned above, load the AddIn. This will create an

                // instance of AddIn EntryPoint class to activate the AddIn.

                if (addInProcess == null)

                {

                    // Load the AddIn in the same process as the host.

                    addIn = addInToken[0].Activate<IEntryPoint>(AddInSecurityLevel.FullTrust);

                }

                else

                {

                    // Load the AddIn in external process.

                    addIn = addInToken[0].Activate<IEntryPoint>(addInProcess, AddInSecurityLevel.FullTrust);

                }

 

                // Initialize AddIn by calling into functions of the AddIn EntryPoint instance.

                addIn.Initialize(this.serviceProvider);

 

                //Start Workaround for AddIn_Startup debug hanging problem

                // Make sure the type-registering thread is started.

                int timesToTry = 50; // 5 seconds;

                bool typeRegisteringThreadStarted = false;

                while ((timesToTry--) > 0 && System.Diagnostics.Debugger.IsAttached)

                {

                    int count = Process.GetCurrentProcess().Threads.Count;

                    if (count >= threadCountBeforeLoadingAddIn + 2)

                    {

                        typeRegisteringThreadStarted = true;

                        Debug.WriteLine("typeRegisteringThreadStartedt: true");

                        break;

                    }

                    Thread.Sleep(100);

                }

                //End Workaround

 

                addIn.InitializeDataBindings();

 

                //Start Workaround for AddIn_Startup debug hanging problem

                timesToTry = 50;

                while ((timesToTry--) > 0 && System.Diagnostics.Debugger.IsAttached)

                {

                    // assume the addin startup does not create new threads.

                    int count = Process.GetCurrentProcess().Threads.Count;

                    if (count == threadCountBeforeLoadingAddIn + 1 && typeRegisteringThreadStarted)

                    {

                        break;

                    }

                    else if (count > threadCountBeforeLoadingAddIn + 1)

                    {

                        typeRegisteringThreadStarted = true;

                    }

                    Debug.WriteLine("thread count: " + count);

                    Thread.Sleep(100);

                }

                // End Workaround

 

                addIn.FinishInitialization();

 

                // Return the loaded AddIn.

                return addIn;

            }

            catch (Exception ex)

            {

                // Do not let error of this AddIn affect others

                System.Diagnostics.Trace.WriteLine(ex.ToString());

                System.Diagnostics.Debug.Assert(false);

 

                return null;

            }

        }

 

 

 

 


Posted Jun 22 2009, 01:48 PM by BillL
Copyright Summit Software Company, 2008. All rights reserved.