11 Replies Latest reply on Sep 8, 2010 5:22 PM by Ahmad Fattahi

    'ContextSwitchDeadlock' message from Managed Debugging Assistant

    richs04

      I am finally debugging my project and after running for about 1.25 minutes I get the following message:

       

      Managed Debugging Assistant 'ContextSwitchDeadlock' has detected a problem in 'C:\Development\pmax\pmax\bin\Debug\pmax.vshost.exe'.
      Additional Information: The CLR has been unable to transition from COM context 0x3f01fb8 to COM context 0x3f02128 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.

       

      If I click Continue my program continues and the message doesn't appear again.  Is there something I need to set in the SDK?  The PISDK is the only COM object in my program.

        • Re: 'ContextSwitchDeadlock' message from Managed Debugging Assistant
          cescamilla

          Is your application stopping in a return call, waiting for a response from the PI SDK for a long time?

            • Re: 'ContextSwitchDeadlock' message from Managed Debugging Assistant
              richs04

              Not that I can tell.  I have trace msgs showing the progress around all the sdk calls.

                • Re: 'ContextSwitchDeadlock' message from Managed Debugging Assistant
                  cescamilla

                  Are you using Visual Basic for your application? is it a Graphical Application?

                    • Re: 'ContextSwitchDeadlock' message from Managed Debugging Assistant
                      cescamilla

                      I have encounter this some times before, but I was really locking the application, since this seems not to be your case, and if you are completely sure that this message is just a nagger, please disable the MDA as described in this link. Let us know if that solves your problem :)

                        • Re: 'ContextSwitchDeadlock' message from Managed Debugging Assistant
                          richs04

                          From the link provided I have the symptons of not allowing a finalized to be called in the SDK because memory usage is increasing by aprox 30k every cycle of my program.  I am not using a lot of SDK functions but I am allocating PISDK.PISDKClass objects and setting them to null when I am finished with them in each cycle.  I also allcate PointList objects, and NamedValues objects.  There seems like there is no clear() for the PointLists.  Is there something I should check when I'm finished with a PISDK object or one of its associated objects before setting it to null?

                            • Re: 'ContextSwitchDeadlock' message from Managed Debugging Assistant
                              cescamilla

                              Why are you instantiating various PISDK.PISDKClass objects? I think that setting them to null will not recollet them until the next Garbage recollection cycle, and even then the objects will not be recollected if there are objects that depend on them. Having just one PISDKClass object should work as well.

                                • Re: 'ContextSwitchDeadlock' message from Managed Debugging Assistant
                                  richs04

                                  I tried to have just one PISDK object but I can't access it from any threads I create.  When I try to access the PISDK object from another thread the reference is trashed, even when I tell the GC to leave it alone.  Some of my increasing memory is comming from my PointList object and PISDKCommon.NamedValues object.  They don't seem to go away, even after a GC.Collect().

                                    • Re: 'ContextSwitchDeadlock' message from Managed Debugging Assistant
                                      cescamilla

                                      Are you using a consola MTA application to do this? why the many threads? you could use Assynchronous calls instead.

                                       

                                       

                                       

                                      Would you like to share some of your code here? I feel like I'm [trouble]shooting in the dark.

                                        • Re: 'ContextSwitchDeadlock' message from Managed Debugging Assistant
                                          richs04

                                          This 1st section of code is the 1st allocation of the SDK.  This ref is not set to null anywhere.  There is also no GC.KeepAlive because I don't care if this one goes away.

                                          PISDK.PISDKClass m_SDK;
                                          PIPoints m_Points =null;//******************************************************************************// Constructor//******************************************************************************public CrossRefFile(){// Make ref to PI SDKtry{
                                            m_SDK =new PISDK.PISDKClass();
                                            m_SDK.ConnectTimeout=20;
                                            // Force connection to PI
                                            string test = m_SDK.Servers[m_PIServerName].ServerTime().LocalDate.ToString();
                                            // Get the current list of PI points
                                            m_Points = m_SDK.Servers[m_PIServerName].PIPoints;
                                            // Are we connected to PI
                                            m_ConnectedToPI = m_SDK.Servers[m_PIServerName].Connected;}catch(System.Runtime.InteropServices.COMException comExc){
                                            CRF_Msg.Record_Msg("Program:Main - PI SDK Failed - "+ comExc.Message, RTimeInterface.MSGTYPE_APP_ERROR, RecordMessage.MSGTYPE.BOTH);
                                            Environment.Exit(-1);}

                                          This 2nd section of code is the 2nd, and final, allocation of the SDK and will be in a thread which will rarely end.  This ref is set to null only when the thread finishes  and is protected with GC.KeepAlive.

                                                  publicvoid ProcessAllPoints()
                                                  {
                                                      // We need a local copy of the PISDK because this method will be a thread
                                                      PISDK.PISDKClass    sdk =null;
                                                      PIPoints            Points =null;
                                                      try
                                                      {
                                                          //Make sure the garbage collector keeps this one alive
                                                          sdk =new PISDK.PISDKClass();
                                                          string test = sdk.Servers[m_PIServerName].ServerTime().LocalDate.ToString();
                                                          Points = sdk.Servers[m_PIServerName].PIPoints;
                                                          GC.KeepAlive(sdk);
                                                      }
                                                      catch(System.Runtime.InteropServices.COMException comExc)
                                                      {
                                                          CRF_Msg.Record_Msg("CrossRefFile:ProcessAllPoints - PI SDK Failed - "+ comExc.Message, RTimeInterface.MSGTYPE_APP_ERROR, RecordMessage.MSGTYPE.BOTH);
                                                      };
                                                      // Allow the seconds to increment
                                                      Subscription.m_Working=false;
                                                      while(!_shouldStop)
                                                      {
                                                          // Have we reached our time period
                                                          if(Subscription.m_Seconds>= m_UpdateRate)
                                                          {
                                                              // Stop the seconds from increment
                                                              Subscription.m_Working=true;
                                                              Subscription.m_Seconds=0;
                                                              // Process all the points and do the data transfer
                                                              // Process the points in each Link
                                                              foreach(Link Lk in m_Links)
                                                              {
                                                                  // Set local ret to the PI Points
                                                                  Lk.m_myPoints= Points;
                                                                  // Set local ref to the PI SDK
                                                                  Lk.m_SDK= sdk;
                                                                  // Process the points in the link
                                                                  Lk.ProcessPoints();
                                                              }
                                                              // Allow the seconds to increment
                                                              Subscription.m_Working=false;
                                                          }
                                                          Thread.Sleep(100);
                                                      }
                                                      Subscription.Finished();
                                                      Points =null;
                                                      sdk =null;
                                                      GC.Collect();
                                                  }


                                          Like before, if I click continue on the timeout message the program continues fine.