Joining a STA thread to a MTA thread

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • mitrrahul
    New Member
    • Jan 2009
    • 8

    Joining a STA thread to a MTA thread

    HI Friends,

    I am facing a problem while joining a STA thread to MTA thread. Actually the requirement was some thing like describe below.
    1. I have a exe which is using some dialog boxes.
    2. These dialog boxes are using MSFlexGrid. This component is a Com component.
    3.so in order to run it with Vb.Net exe i had to run this dialog box in a STA thread.
    4. to achive this i created a new thread and set the Apartment status STA.
    5.it was working fine when i run the code. but if click on exe than at the time of join it throws an unhandled exception.if i click on continue button of exception dialog box it runs successfully. how ever i can not ignore this exception.
    6. exception contains below text (i know its a bog message but i am stuck here for last couple of days.).


    ************** Exception Text **************
    System.AccessVi olationExceptio n: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
    at MSFlexGridLib.I MSFlexGrid.get_ Text()
    at AxMSFlexGridLib .AxMSFlexGrid.g et_Text()
    at System.Windows. Forms.Control.O nHandleDestroye d(EventArgs e)
    at System.Windows. Forms.AxHost.De tachWindow()
    at System.Windows. Forms.AxHost.De tachAndForward( Message& m)
    at System.Windows. Forms.AxHost.Wn dProc(Message& m)
    at System.Windows. Forms.Control.C ontrolNativeWin dow.OnMessage(M essage& m)
    at System.Windows. Forms.Control.C ontrolNativeWin dow.WndProc(Mes sage& m)
    at System.Windows. Forms.NativeWin dow.Callback(In tPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

    7. COde snippet is like below.
    [CODE=vbnet]]
    Dim paramtThread As New Threading.Param eterizedThreadS tart(AddressOf DelgInvoke)
    Dim exeThread As New Threading.Threa d(paramtThread)
    exeThread.SetAp artmentState(Th reading.Apartme ntState.STA)
    exeThread.Start (mbrs)// mbrs is a structure variable.
    exeThread.Join( )
    [/code]
    [CODE=vbnet] Private Function DelgInvoke(ByVa l mbrs2 As Members) As Boolean
    m_bResFromExeTh read = False
    m_bResFromExeTh read = mbrs2.oJobTask. Execute(mbrs2.o PrinterStatus, mbrs2.nError, mbrs2.strError)
    Return m_bResFromExeTh read

    End Function[/CODE]

    Please let me know if any one have any idea. i am totaly clueless here. it would be a great help.
  • Plater
    Recognized Expert Expert
    • Apr 2007
    • 7872

    #2
    Can you make your whole project STA?
    Or rather make a secondary thread that calls and starts that thread as a third thread?

    Also, why are you using msflexgrid? Are you aware of DataGridView?

    Comment

    • mitrrahul
      New Member
      • Jan 2009
      • 8

      #3
      Actually its a very large Vb6.0 to VB.Net migrated project. it contains some 16 components. i can not make whole project as STA.
      i know about DataGridView but right now its not possible to change the component, as its being used in many other applications. I had a problem with msflexgrid. so i created a thread and set the apartment as STA. initially it was working fine(or may be i ignored the error). but now it gives me the above mentioned error. i just wanted to know if there is any guideline to join a STA with MTA. i have tried event mechanism also, but it seems like when this thread dies it gives this error.

      Comment

      • Plater
        Recognized Expert Expert
        • Apr 2007
        • 7872

        #4
        Why do you call a Join() right after the Start()?

        EDIT: Nevermind that I suppose.

        What if you made your own version of Join()?
        Something like looping while that thread is still active.
        And in your loop you would call
        Application.DoE vents
        and
        Thread.Sleep(10 0)

        And maybe checking a DateTime object if you don't want it to wait forever

        Comment

        • mitrrahul
          New Member
          • Jan 2009
          • 8

          #5
          Actually as soon as i say thread.start(). it start executing the function delgInvoke(). Main thread keep waiting for child thread until it finishes. so i am using join() here(for wait forever).

          Comment

          • Plater
            Recognized Expert Expert
            • Apr 2007
            • 7872

            #6
            Right.
            But you said Join() is where the exception is thrown right?
            So what if you don't use it and implememnt you own blocking/waiting?

            Comment

            • mitrrahul
              New Member
              • Jan 2009
              • 8

              #7
              If i don't use Join() and use some other methods like events, still i get the same problem :(.

              Comment

              • Plater
                Recognized Expert Expert
                • Apr 2007
                • 7872

                #8
                All of the creation and destruction of the COM object is happening inside that thread right?
                You don't like wait for the thread to close then try to dispose of the com object do you?

                Comment

                • mitrrahul
                  New Member
                  • Jan 2009
                  • 8

                  #9
                  Yes all creation and destruction of com object is happening inside the thread. i have a doubt regarding the destruction of a com object. as i have mentioned i am using MSFlexgrid. and its being used in that thread so can you point out the place where should i dispose that object. i mean as i say thread.start() and just after this call am using join()( orsome other wait mechanism). so should i wait for some time here?

                  Comment

                  • vekipeki
                    Recognized Expert New Member
                    • Nov 2007
                    • 229

                    #10
                    When you added the MSFlexGrid control to your second form, .Net created the wrapper class (AxMSFlexGrid), which handles the COM interop. You shouldn't worry about disposing it manually, since it will be disposed when your second form is disposed (providing that you simply added it to the form using the VS designer).

                    You said that you get the same error even without Joining, so the problem shouldn't be with joining. Also, there is no such thing as STA and MTA threads. Using the STA attribute will only tell .Net to initialize COM in STA and marshal all calls to that COM object through a single (the one and only) apartment thread; 'exeThread' is therefore just a thread like any other, marshaling only occurs during calls to COM.

                    How does the 'mbrs2.oJobTask .Execute' line create the new Form? Are you using ShowDialog or Show with some event handling? I am asking this because in the second case (non modal) you will probably have to use Application.Run to create the form properly.

                    Comment

                    • mitrrahul
                      New Member
                      • Jan 2009
                      • 8

                      #11
                      Actually mbrs2.oJobTask. Execute() calls a dialog box say dlgUpload. this dialog box is using a Activex control ctrlPrompt and this ctrlPrompt is using another actiavex control UserDefinput. This UserDefInput is using MSFlexgrid.
                      Actually as you can see in error descirpiton. i am getting the error in MSFlexGrid. so i was confused if i am doing the right things here. i mean should i do some thing explicit ot dispose this msflexgrid?

                      Comment

                      • vekipeki
                        Recognized Expert New Member
                        • Nov 2007
                        • 229

                        #12
                        But all these controls are from VB6, and you added them using the Designer, not manually, right? I guess you could go through that old code to see if something is not disposed properly related to msflexgrid, but to dispose a child control in another control is not a very good practice.

                        The only thing that you should do about disposing is to put your dialog form code in a "using" block to ensure that the Dispose method is called immediately after its use.

                        Comment

                        • mitrrahul
                          New Member
                          • Jan 2009
                          • 8

                          #13
                          All are Vb6.0 to VB.NET 2008 migrated components. when i run the code((Debug/Release mode)) it works fine but if i click on any exe(Debug/Release) it gives me the above mentioned exception.how ever if click on continue button of exception it works ok. but i need to find out the cause because if i enable the JIT debugging then i dont get the excptio dialog box and my threads get hanged some where in middle of the application.

                          Comment

                          • mitrrahul
                            New Member
                            • Jan 2009
                            • 8

                            #14
                            yes i added them through designer not manually.

                            Comment

                            Working...