ThreadPool and COM+

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Duane Pressley

    ThreadPool and COM+

    I'm looking for someone to help me make sense of the results I'm observing when using the ThreadPool class in a COM-Interop scenario. Here's the set up:
    1.. A classic ASP page instantiates and calls MethodA on COM+ Class (C1).
    2.. MethodA of COM+ class (C1) instantiates and calls MethodB of .NET class (N1). (Note: N1 has been registered using RegASM and is present in the GAC).
    3.. MethodB of .NET class (N1) uses the ThreadPool.Queu eUserWorkItem method to queue up a call to MethodC on .NET Class (N2).
    4.. MethodC of .NET Class (N2), (called on a ThreadPool thread), instantiates and calls MethodD on COM+ class (C2).
    5.. MethodD of COM+ Class (C2) instantiates and calls MethodE on COM+ class (C3).
    6.. Finally, methodB of .NET Class (N1) uses static members of .NET Class (N2) to retrieve the results of the "background " processing. These results are passed back to COM+ Class (C1) and ultimately displayed on the ASP page.
    Note: All COM+ classes are registered within the same COM+ application; and this application is configured as a "Library" application.

    I believe this sequence of calls results in the following transitions:
    1.. An IIS worker thread, (running C1), transitions to .NET managed thread, (running N1). I'm not at all clear as to what process owns the ..NET thread.
    2.. As a result of item#1 a .NET ThreadPool thread, (running N2), transitions to a COM+ thread, (running C2).
    3.. I'm assuming the same COM+ Thread from item#2 is used to run C3.
    4.. The COM+ Thread running C2 and C3 completes and transitions back to the .NET ThreadPool thread running N2.
    5.. Based on a flag exposed as a static member of N2, the "original" ..NET Thread begins accessing static members of N2. (These static members are used to aggregate results across multiple ThreadPool threads.)
    6.. Finally, the "original" .NET thread transitions back to the IIS worker thread running C1.
    After modifying Machine.Config such that the "ProcessMod el" tag used the "system" account instead of the "machine" account, I was able to get this working in Debug mode. The modification was required to enable transition #2 (listed above). Prior to making this modification an exception was thrown indicating an inability to call COM+ class C2. (Sorry, I don't recall the exact exception.)

    When I say Debug mode, I'm referring to running the code within the VS.NET and VS6 IDEs and stepping between break points.

    With everything working in Debug mode, I then attempted to execute the code without debugging. Based on well placed App.LogEvent and EventLog.WriteE ntry calls, it appears that the following is occurring:
    1.. All calls prior to the calling of COM+ Class C3 appear to be working.
    2.. The Call to COM+ Class C3 doesn't raise a COM+ error, but the variant returned from this call is empty. During successful execution the resulting variant contains an array with a "UBound" of 5. The real puzzling thing about this situation is that an error with COM+ class C3 should result in a variant containing an array with a "UBound" of 3. There should always be an array returned from COM+ C3!
    So the questions are as follows:
    1.. Is it possible that the return values, (which are passed ByRef), aren't being marshalled properly between COM+ Class C2 and COM+ Class C3?
    2.. Is it possible that the call from COM+ Class C2 to COM+ Class C3 is failing silently? (Placing App.LogEvent calls within COM+ Class C3 requires the involvement of another team.)
    3.. Is there some security or thread related issue here that I'm just not seeing? And does this underlying issue explain why things work during Debug and fail when not running under an IDE managed thread?
    Thanks for taking the time to read all of that. :-)
  • Nicholas Paldino [.NET/C# MVP]

    #2
    Re: ThreadPool and COM+

    Duane,

    I believe that there is a threading issue here that could be
    contributing to some of the issues you are seeing. The threads in the
    ThreadPool class do not belong to any COM compartment by default. This is a
    big issue, because components that derive from ServicedCompone nt are not
    free-threaded. From the section of the .NET framework documentation titled
    "Managed and Unmanaged Threading in Microsoft Windows":

    Managed objects that are exposed to COM behave as if they had aggregated the
    free-threaded marshaler. In other words, they can be called from any COM
    apartment in a free-threaded manner. The only managed objects that do not
    exhibit this free-threaded behavior are those objects that derive from
    ServicedCompone nt.

    Since you declared that your components are COM+ components, I'm
    assuming they are all derived from ServicedCompone nt.

    Because the apartment is not set up correctly, you probably are not
    getting the correct context for your components, which can result in a
    number of the issues that you are seeing.

    Hope this helps.

    --
    - Nicholas Paldino [.NET/C# MVP]
    - casper(1 spelled out){at)caspers (where I live, rhymes with
    mouse)<dot]com

    "Duane Pressley" <DuaneP@AdminSe rver.com> wrote in message
    news:eayX%23e1h DHA.2496@tk2msf tngp13.phx.gbl. ..
    I'm looking for someone to help me make sense of the results I'm observing
    when using the ThreadPool class in a COM-Interop scenario. Here's the set
    up:
    A classic ASP page instantiates and calls MethodA on COM+ Class (C1).
    MethodA of COM+ class (C1) instantiates and calls MethodB of .NET class
    (N1). (Note: N1 has been registered using RegASM and is present in the GAC).
    MethodB of .NET class (N1) uses the ThreadPool.Queu eUserWorkItem method to
    queue up a call to MethodC on .NET Class (N2).
    MethodC of .NET Class (N2), (called on a ThreadPool thread), instantiates
    and calls MethodD on COM+ class (C2).
    MethodD of COM+ Class (C2) instantiates and calls MethodE on COM+ class
    (C3).
    Finally, methodB of .NET Class (N1) uses static members of .NET Class (N2)
    to retrieve the results of the "background " processing. These results are
    passed back to COM+ Class (C1) and ultimately displayed on the ASP page.
    Note: All COM+ classes are registered within the same COM+ application;
    and this application is configured as a "Library" application.

    I believe this sequence of calls results in the following transitions:
    An IIS worker thread, (running C1), transitions to .NET managed thread,
    (running N1). I'm not at all clear as to what process owns the .NET thread.
    As a result of item#1 a .NET ThreadPool thread, (running N2), transitions to
    a COM+ thread, (running C2).
    I'm assuming the same COM+ Thread from item#2 is used to run C3.
    The COM+ Thread running C2 and C3 completes and transitions back to the .NET
    ThreadPool thread running N2.
    Based on a flag exposed as a static member of N2, the "original" .NET Thread
    begins accessing static members of N2. (These static members are used to
    aggregate results across multiple ThreadPool threads.)
    Finally, the "original" .NET thread transitions back to the IIS worker
    thread running C1.
    After modifying Machine.Config such that the "ProcessMod el" tag used the
    "system" account instead of the "machine" account, I was able to get this
    working in Debug mode. The modification was required to enable transition #2
    (listed above). Prior to making this modification an exception was thrown
    indicating an inability to call COM+ class C2. (Sorry, I don't recall the
    exact exception.)

    When I say Debug mode, I'm referring to running the code within the
    VS.NET and VS6 IDEs and stepping between break points.

    With everything working in Debug mode, I then attempted to execute the code
    without debugging. Based on well placed App.LogEvent and EventLog.WriteE ntry
    calls, it appears that the following is occurring:
    All calls prior to the calling of COM+ Class C3 appear to be working.
    The Call to COM+ Class C3 doesn't raise a COM+ error, but the variant
    returned from this call is empty. During successful execution the resulting
    variant contains an array with a "UBound" of 5. The real puzzling thing
    about this situation is that an error with COM+ class C3 should result in a
    variant containing an array with a "UBound" of 3. There should always be an
    array returned from COM+ C3!
    So the questions are as follows:
    Is it possible that the return values, (which are passed ByRef), aren't
    being marshalled properly between COM+ Class C2 and COM+ Class C3?
    Is it possible that the call from COM+ Class C2 to COM+ Class C3 is failing
    silently? (Placing App.LogEvent calls within COM+ Class C3 requires the
    involvement of another team.)
    Is there some security or thread related issue here that I'm just not
    seeing? And does this underlying issue explain why things work during Debug
    and fail when not running under an IDE managed thread?
    Thanks for taking the time to read all of that. :-)


    Comment

    • Duane Pressley

      #3
      Re: ThreadPool and COM+

      Thanks for the reply Nicholas.

      To clarify things a bit:
      1.. There are 2 .NET classes in my scenario, and neither of these are derived from ServicedCompone nt.
      2.. The COM+ classes involved, (C1, C2, and C3), are all members of the same COM+ application.
      Are you suggesting that I should move one of my .NET classes into COM+?

      In an attempt to explore your thoughts that this may be related to the COM apartment of the ThreadPool thread, I did the following:
      1.. Marked the N2 method, (this is the method run on the ThreadPool thread), with the [STAThread] attribute. This produced the same results.
      2.. Used the Thread.CurrentT hread.Apartment State property to set the ApartmentState to STA. Again same results as before.
      Thanks for the post...any other ideas?
      "Nicholas Paldino [.NET/C# MVP]" <casper(1 spelled out){at)caspers (where I live, rhymes with mouse)<dot]com> wrote in message news:u0FXRt1hDH A.3204@TK2MSFTN GP11.phx.gbl...[color=blue]
      > Duane,
      >
      > I believe that there is a threading issue here that could be
      > contributing to some of the issues you are seeing. The threads in the
      > ThreadPool class do not belong to any COM compartment by default. This is a
      > big issue, because components that derive from ServicedCompone nt are not
      > free-threaded. From the section of the .NET framework documentation titled
      > "Managed and Unmanaged Threading in Microsoft Windows":
      >
      > Managed objects that are exposed to COM behave as if they had aggregated the
      > free-threaded marshaler. In other words, they can be called from any COM
      > apartment in a free-threaded manner. The only managed objects that do not
      > exhibit this free-threaded behavior are those objects that derive from
      > ServicedCompone nt.
      >
      > Since you declared that your components are COM+ components, I'm
      > assuming they are all derived from ServicedCompone nt.
      >
      > Because the apartment is not set up correctly, you probably are not
      > getting the correct context for your components, which can result in a
      > number of the issues that you are seeing.
      >
      > Hope this helps.
      >
      > --
      > - Nicholas Paldino [.NET/C# MVP]
      > - casper(1 spelled out){at)caspers (where I live, rhymes with
      > mouse)<dot]com
      >
      > "Duane Pressley" <DuaneP@AdminSe rver.com> wrote in message
      > news:eayX%23e1h DHA.2496@tk2msf tngp13.phx.gbl. ..
      > I'm looking for someone to help me make sense of the results I'm observing
      > when using the ThreadPool class in a COM-Interop scenario. Here's the set
      > up:
      > A classic ASP page instantiates and calls MethodA on COM+ Class (C1).
      > MethodA of COM+ class (C1) instantiates and calls MethodB of .NET class
      > (N1). (Note: N1 has been registered using RegASM and is present in the GAC).
      > MethodB of .NET class (N1) uses the ThreadPool.Queu eUserWorkItem method to
      > queue up a call to MethodC on .NET Class (N2).
      > MethodC of .NET Class (N2), (called on a ThreadPool thread), instantiates
      > and calls MethodD on COM+ class (C2).
      > MethodD of COM+ Class (C2) instantiates and calls MethodE on COM+ class
      > (C3).
      > Finally, methodB of .NET Class (N1) uses static members of .NET Class (N2)
      > to retrieve the results of the "background " processing. These results are
      > passed back to COM+ Class (C1) and ultimately displayed on the ASP page.
      > Note: All COM+ classes are registered within the same COM+ application;
      > and this application is configured as a "Library" application.
      >
      > I believe this sequence of calls results in the following transitions:
      > An IIS worker thread, (running C1), transitions to .NET managed thread,
      > (running N1). I'm not at all clear as to what process owns the .NET thread.
      > As a result of item#1 a .NET ThreadPool thread, (running N2), transitions to
      > a COM+ thread, (running C2).
      > I'm assuming the same COM+ Thread from item#2 is used to run C3.
      > The COM+ Thread running C2 and C3 completes and transitions back to the .NET
      > ThreadPool thread running N2.
      > Based on a flag exposed as a static member of N2, the "original" .NET Thread
      > begins accessing static members of N2. (These static members are used to
      > aggregate results across multiple ThreadPool threads.)
      > Finally, the "original" .NET thread transitions back to the IIS worker
      > thread running C1.
      > After modifying Machine.Config such that the "ProcessMod el" tag used the
      > "system" account instead of the "machine" account, I was able to get this
      > working in Debug mode. The modification was required to enable transition #2
      > (listed above). Prior to making this modification an exception was thrown
      > indicating an inability to call COM+ class C2. (Sorry, I don't recall the
      > exact exception.)
      >
      > When I say Debug mode, I'm referring to running the code within the
      > VS.NET and VS6 IDEs and stepping between break points.
      >
      > With everything working in Debug mode, I then attempted to execute the code
      > without debugging. Based on well placed App.LogEvent and EventLog.WriteE ntry
      > calls, it appears that the following is occurring:
      > All calls prior to the calling of COM+ Class C3 appear to be working.
      > The Call to COM+ Class C3 doesn't raise a COM+ error, but the variant
      > returned from this call is empty. During successful execution the resulting
      > variant contains an array with a "UBound" of 5. The real puzzling thing
      > about this situation is that an error with COM+ class C3 should result in a
      > variant containing an array with a "UBound" of 3. There should always be an
      > array returned from COM+ C3!
      > So the questions are as follows:
      > Is it possible that the return values, (which are passed ByRef), aren't
      > being marshalled properly between COM+ Class C2 and COM+ Class C3?
      > Is it possible that the call from COM+ Class C2 to COM+ Class C3 is failing
      > silently? (Placing App.LogEvent calls within COM+ Class C3 requires the
      > involvement of another team.)
      > Is there some security or thread related issue here that I'm just not
      > seeing? And does this underlying issue explain why things work during Debug
      > and fail when not running under an IDE managed thread?
      > Thanks for taking the time to read all of that. :-)
      >
      >[/color]

      Comment

      • Duane Pressley

        #4
        Re: ThreadPool and COM+

        After further review, it appears that my problem was due to an apparent inability to call an in-process STA COM+ Class from a MTA "ThreadPool " thread.

        Moving COM+ Class (C2) to an out-of-process "Server" application allowed me to "work-around" my initial issue.

        Does anyone know if it is possible to successfully call an in-process STA COM+ Class from a "ThreadPool " thread?


        "Duane Pressley" <DuaneP@AdminSe rver.com> wrote in message news:eGI8UV3hDH A.964@TK2MSFTNG P12.phx.gbl...
        Thanks for the reply Nicholas.

        To clarify things a bit:
        1.. There are 2 .NET classes in my scenario, and neither of these are derived from ServicedCompone nt.
        2.. The COM+ classes involved, (C1, C2, and C3), are all members of the same COM+ application.
        Are you suggesting that I should move one of my .NET classes into COM+?

        In an attempt to explore your thoughts that this may be related to the COM apartment of the ThreadPool thread, I did the following:
        1.. Marked the N2 method, (this is the method run on the ThreadPool thread), with the [STAThread] attribute. This produced the same results.
        2.. Used the Thread.CurrentT hread.Apartment State property to set the ApartmentState to STA. Again same results as before.
        Thanks for the post...any other ideas?
        "Nicholas Paldino [.NET/C# MVP]" <casper(1 spelled out){at)caspers (where I live, rhymes with mouse)<dot]com> wrote in message news:u0FXRt1hDH A.3204@TK2MSFTN GP11.phx.gbl...[color=blue]
        > Duane,
        >
        > I believe that there is a threading issue here that could be
        > contributing to some of the issues you are seeing. The threads in the
        > ThreadPool class do not belong to any COM compartment by default. This is a
        > big issue, because components that derive from ServicedCompone nt are not
        > free-threaded. From the section of the .NET framework documentation titled
        > "Managed and Unmanaged Threading in Microsoft Windows":
        >
        > Managed objects that are exposed to COM behave as if they had aggregated the
        > free-threaded marshaler. In other words, they can be called from any COM
        > apartment in a free-threaded manner. The only managed objects that do not
        > exhibit this free-threaded behavior are those objects that derive from
        > ServicedCompone nt.
        >
        > Since you declared that your components are COM+ components, I'm
        > assuming they are all derived from ServicedCompone nt.
        >
        > Because the apartment is not set up correctly, you probably are not
        > getting the correct context for your components, which can result in a
        > number of the issues that you are seeing.
        >
        > Hope this helps.
        >
        > --
        > - Nicholas Paldino [.NET/C# MVP]
        > - casper(1 spelled out){at)caspers (where I live, rhymes with
        > mouse)<dot]com
        >
        > "Duane Pressley" <DuaneP@AdminSe rver.com> wrote in message
        > news:eayX%23e1h DHA.2496@tk2msf tngp13.phx.gbl. ..
        > I'm looking for someone to help me make sense of the results I'm observing
        > when using the ThreadPool class in a COM-Interop scenario. Here's the set
        > up:
        > A classic ASP page instantiates and calls MethodA on COM+ Class (C1).
        > MethodA of COM+ class (C1) instantiates and calls MethodB of .NET class
        > (N1). (Note: N1 has been registered using RegASM and is present in the GAC).
        > MethodB of .NET class (N1) uses the ThreadPool.Queu eUserWorkItem method to
        > queue up a call to MethodC on .NET Class (N2).
        > MethodC of .NET Class (N2), (called on a ThreadPool thread), instantiates
        > and calls MethodD on COM+ class (C2).
        > MethodD of COM+ Class (C2) instantiates and calls MethodE on COM+ class
        > (C3).
        > Finally, methodB of .NET Class (N1) uses static members of .NET Class (N2)
        > to retrieve the results of the "background " processing. These results are
        > passed back to COM+ Class (C1) and ultimately displayed on the ASP page.
        > Note: All COM+ classes are registered within the same COM+ application;
        > and this application is configured as a "Library" application.
        >
        > I believe this sequence of calls results in the following transitions:
        > An IIS worker thread, (running C1), transitions to .NET managed thread,
        > (running N1). I'm not at all clear as to what process owns the .NET thread.
        > As a result of item#1 a .NET ThreadPool thread, (running N2), transitions to
        > a COM+ thread, (running C2).
        > I'm assuming the same COM+ Thread from item#2 is used to run C3.
        > The COM+ Thread running C2 and C3 completes and transitions back to the .NET
        > ThreadPool thread running N2.
        > Based on a flag exposed as a static member of N2, the "original" ..NET Thread
        > begins accessing static members of N2. (These static members are used to
        > aggregate results across multiple ThreadPool threads.)
        > Finally, the "original" .NET thread transitions back to the IIS worker
        > thread running C1.
        > After modifying Machine.Config such that the "ProcessMod el" tag used the
        > "system" account instead of the "machine" account, I was able to get this
        > working in Debug mode. The modification was required to enable transition #2
        > (listed above). Prior to making this modification an exception was thrown
        > indicating an inability to call COM+ class C2. (Sorry, I don't recall the
        > exact exception.)
        >
        > When I say Debug mode, I'm referring to running the code within the
        > VS.NET and VS6 IDEs and stepping between break points.
        >
        > With everything working in Debug mode, I then attempted to execute the code
        > without debugging. Based on well placed App.LogEvent and EventLog.WriteE ntry
        > calls, it appears that the following is occurring:
        > All calls prior to the calling of COM+ Class C3 appear to be working.
        > The Call to COM+ Class C3 doesn't raise a COM+ error, but the variant
        > returned from this call is empty. During successful execution the resulting
        > variant contains an array with a "UBound" of 5. The real puzzling thing
        > about this situation is that an error with COM+ class C3 should result in a
        > variant containing an array with a "UBound" of 3. There should always be an
        > array returned from COM+ C3!
        > So the questions are as follows:
        > Is it possible that the return values, (which are passed ByRef), aren't
        > being marshalled properly between COM+ Class C2 and COM+ Class C3?
        > Is it possible that the call from COM+ Class C2 to COM+ Class C3 is failing
        > silently? (Placing App.LogEvent calls within COM+ Class C3 requires the
        > involvement of another team.)
        > Is there some security or thread related issue here that I'm just not
        > seeing? And does this underlying issue explain why things work during Debug
        > and fail when not running under an IDE managed thread?
        > Thanks for taking the time to read all of that. :-)
        >
        >[/color]

        Comment

        • Mr.Tickle

          #5
          Re: ThreadPool and COM+

          If i use the threadpool for like 3.. to 5 threads , is there a gurantee that they will be started pretty close to when i requested them? or what would make them wait somehow, is there a way to determine that after a period of time that a thread pooled hasnt started then i can abort it and do a new thread start?


          "Duane Pressley" <DuaneP@AdminSe rver.com> wrote in message news:OsWgSnSiDH A.1796@TK2MSFTN GP10.phx.gbl...
          After further review, it appears that my problem was due to an apparent inability to call an in-process STA COM+ Class from a MTA "ThreadPool " thread.

          Moving COM+ Class (C2) to an out-of-process "Server" application allowed me to "work-around" my initial issue.

          Does anyone know if it is possible to successfully call an in-process STA COM+ Class from a "ThreadPool " thread?


          "Duane Pressley" <DuaneP@AdminSe rver.com> wrote in message news:eGI8UV3hDH A.964@TK2MSFTNG P12.phx.gbl...
          Thanks for the reply Nicholas.

          To clarify things a bit:
          1.. There are 2 .NET classes in my scenario, and neither of these are derived from ServicedCompone nt.
          2.. The COM+ classes involved, (C1, C2, and C3), are all members of the same COM+ application.
          Are you suggesting that I should move one of my .NET classes into COM+?

          In an attempt to explore your thoughts that this may be related to the COM apartment of the ThreadPool thread, I did the following:
          1.. Marked the N2 method, (this is the method run on the ThreadPool thread), with the [STAThread] attribute. This produced the same results.
          2.. Used the Thread.CurrentT hread.Apartment State property to set the ApartmentState to STA. Again same results as before.
          Thanks for the post...any other ideas?
          "Nicholas Paldino [.NET/C# MVP]" <casper(1 spelled out){at)caspers (where I live, rhymes with mouse)<dot]com> wrote in message news:u0FXRt1hDH A.3204@TK2MSFTN GP11.phx.gbl...[color=blue]
          > Duane,
          >
          > I believe that there is a threading issue here that could be
          > contributing to some of the issues you are seeing. The threads in the
          > ThreadPool class do not belong to any COM compartment by default. This is a
          > big issue, because components that derive from ServicedCompone nt are not
          > free-threaded. From the section of the .NET framework documentation titled
          > "Managed and Unmanaged Threading in Microsoft Windows":
          >
          > Managed objects that are exposed to COM behave as if they had aggregated the
          > free-threaded marshaler. In other words, they can be called from any COM
          > apartment in a free-threaded manner. The only managed objects that do not
          > exhibit this free-threaded behavior are those objects that derive from
          > ServicedCompone nt.
          >
          > Since you declared that your components are COM+ components, I'm
          > assuming they are all derived from ServicedCompone nt.
          >
          > Because the apartment is not set up correctly, you probably are not
          > getting the correct context for your components, which can result in a
          > number of the issues that you are seeing.
          >
          > Hope this helps.
          >
          > --
          > - Nicholas Paldino [.NET/C# MVP]
          > - casper(1 spelled out){at)caspers (where I live, rhymes with
          > mouse)<dot]com
          >
          > "Duane Pressley" <DuaneP@AdminSe rver.com> wrote in message
          > news:eayX%23e1h DHA.2496@tk2msf tngp13.phx.gbl. ..
          > I'm looking for someone to help me make sense of the results I'm observing
          > when using the ThreadPool class in a COM-Interop scenario. Here's the set
          > up:
          > A classic ASP page instantiates and calls MethodA on COM+ Class (C1).
          > MethodA of COM+ class (C1) instantiates and calls MethodB of .NET class
          > (N1). (Note: N1 has been registered using RegASM and is present in the GAC).
          > MethodB of .NET class (N1) uses the ThreadPool.Queu eUserWorkItem method to
          > queue up a call to MethodC on .NET Class (N2).
          > MethodC of .NET Class (N2), (called on a ThreadPool thread), instantiates
          > and calls MethodD on COM+ class (C2).
          > MethodD of COM+ Class (C2) instantiates and calls MethodE on COM+ class
          > (C3).
          > Finally, methodB of .NET Class (N1) uses static members of .NET Class (N2)
          > to retrieve the results of the "background " processing. These results are
          > passed back to COM+ Class (C1) and ultimately displayed on the ASP page.
          > Note: All COM+ classes are registered within the same COM+ application;
          > and this application is configured as a "Library" application.
          >
          > I believe this sequence of calls results in the following transitions:
          > An IIS worker thread, (running C1), transitions to .NET managed thread,
          > (running N1). I'm not at all clear as to what process owns the ..NET thread.
          > As a result of item#1 a .NET ThreadPool thread, (running N2), transitions to
          > a COM+ thread, (running C2).
          > I'm assuming the same COM+ Thread from item#2 is used to run C3.
          > The COM+ Thread running C2 and C3 completes and transitions back to the .NET
          > ThreadPool thread running N2.
          > Based on a flag exposed as a static member of N2, the "original" ..NET Thread
          > begins accessing static members of N2. (These static members are used to
          > aggregate results across multiple ThreadPool threads.)
          > Finally, the "original" .NET thread transitions back to the IIS worker
          > thread running C1.
          > After modifying Machine.Config such that the "ProcessMod el" tag used the
          > "system" account instead of the "machine" account, I was able to get this
          > working in Debug mode. The modification was required to enable transition #2
          > (listed above). Prior to making this modification an exception was thrown
          > indicating an inability to call COM+ class C2. (Sorry, I don't recall the
          > exact exception.)
          >
          > When I say Debug mode, I'm referring to running the code within the
          > VS.NET and VS6 IDEs and stepping between break points.
          >
          > With everything working in Debug mode, I then attempted to execute the code
          > without debugging. Based on well placed App.LogEvent and EventLog.WriteE ntry
          > calls, it appears that the following is occurring:
          > All calls prior to the calling of COM+ Class C3 appear to be working.
          > The Call to COM+ Class C3 doesn't raise a COM+ error, but the variant
          > returned from this call is empty. During successful execution the resulting
          > variant contains an array with a "UBound" of 5. The real puzzling thing
          > about this situation is that an error with COM+ class C3 should result in a
          > variant containing an array with a "UBound" of 3. There should always be an
          > array returned from COM+ C3!
          > So the questions are as follows:
          > Is it possible that the return values, (which are passed ByRef), aren't
          > being marshalled properly between COM+ Class C2 and COM+ Class C3?
          > Is it possible that the call from COM+ Class C2 to COM+ Class C3 is failing
          > silently? (Placing App.LogEvent calls within COM+ Class C3 requires the
          > involvement of another team.)
          > Is there some security or thread related issue here that I'm just not
          > seeing? And does this underlying issue explain why things work during Debug
          > and fail when not running under an IDE managed thread?
          > Thanks for taking the time to read all of that. :-)
          >
          >[/color]

          Comment

          • Duane Pressley

            #6
            Re: ThreadPool and COM+

            My experiences so far suggest that you are unable to "predict" when the ThreadPool threads will be started. The the ThreadPool process appears to start the "background " threads based on CPU availability.

            Keep in mind, there is no way to "cancel" a "work item" that has been queued using the ThreadPool.Queu eUserWorkItem method. You may need to manage your own pool of threads which would allow to have complete control over the starting, stopping, and aborting of those threads.

            Hope that helps.
            "Mr.Tickle" <MrTickle@mrmen .com> wrote in message news:uQcE16SiDH A.2120@TK2MSFTN GP10.phx.gbl...
            If i use the threadpool for like 3.. to 5 threads , is there a gurantee that they will be started pretty close to when i requested them? or what would make them wait somehow, is there a way to determine that after a period of time that a thread pooled hasnt started then i can abort it and do a new thread start?


            "Duane Pressley" <DuaneP@AdminSe rver.com> wrote in message news:OsWgSnSiDH A.1796@TK2MSFTN GP10.phx.gbl...
            After further review, it appears that my problem was due to an apparent inability to call an in-process STA COM+ Class from a MTA "ThreadPool " thread.

            Moving COM+ Class (C2) to an out-of-process "Server" application allowed me to "work-around" my initial issue.

            Does anyone know if it is possible to successfully call an in-process STA COM+ Class from a "ThreadPool " thread?


            "Duane Pressley" <DuaneP@AdminSe rver.com> wrote in message news:eGI8UV3hDH A.964@TK2MSFTNG P12.phx.gbl...
            Thanks for the reply Nicholas.

            To clarify things a bit:
            1.. There are 2 .NET classes in my scenario, and neither of these are derived from ServicedCompone nt.
            2.. The COM+ classes involved, (C1, C2, and C3), are all members of the same COM+ application.
            Are you suggesting that I should move one of my .NET classes into COM+?

            In an attempt to explore your thoughts that this may be related to the COM apartment of the ThreadPool thread, I did the following:
            1.. Marked the N2 method, (this is the method run on the ThreadPool thread), with the [STAThread] attribute. This produced the same results.
            2.. Used the Thread.CurrentT hread.Apartment State property to set the ApartmentState to STA. Again same results as before.
            Thanks for the post...any other ideas?
            "Nicholas Paldino [.NET/C# MVP]" <casper(1 spelled out){at)caspers (where I live, rhymes with mouse)<dot]com> wrote in message news:u0FXRt1hDH A.3204@TK2MSFTN GP11.phx.gbl...[color=blue]
            > Duane,
            >
            > I believe that there is a threading issue here that could be
            > contributing to some of the issues you are seeing. The threads in the
            > ThreadPool class do not belong to any COM compartment by default. This is a
            > big issue, because components that derive from ServicedCompone nt are not
            > free-threaded. From the section of the .NET framework documentation titled
            > "Managed and Unmanaged Threading in Microsoft Windows":
            >
            > Managed objects that are exposed to COM behave as if they had aggregated the
            > free-threaded marshaler. In other words, they can be called from any COM
            > apartment in a free-threaded manner. The only managed objects that do not
            > exhibit this free-threaded behavior are those objects that derive from
            > ServicedCompone nt.
            >
            > Since you declared that your components are COM+ components, I'm
            > assuming they are all derived from ServicedCompone nt.
            >
            > Because the apartment is not set up correctly, you probably are not
            > getting the correct context for your components, which can result in a
            > number of the issues that you are seeing.
            >
            > Hope this helps.
            >
            > --
            > - Nicholas Paldino [.NET/C# MVP]
            > - casper(1 spelled out){at)caspers (where I live, rhymes with
            > mouse)<dot]com
            >
            > "Duane Pressley" <DuaneP@AdminSe rver.com> wrote in message
            > news:eayX%23e1h DHA.2496@tk2msf tngp13.phx.gbl. ..
            > I'm looking for someone to help me make sense of the results I'm observing
            > when using the ThreadPool class in a COM-Interop scenario. Here's the set
            > up:
            > A classic ASP page instantiates and calls MethodA on COM+ Class (C1).
            > MethodA of COM+ class (C1) instantiates and calls MethodB of ..NET class
            > (N1). (Note: N1 has been registered using RegASM and is present in the GAC).
            > MethodB of .NET class (N1) uses the ThreadPool.Queu eUserWorkItem method to
            > queue up a call to MethodC on .NET Class (N2).
            > MethodC of .NET Class (N2), (called on a ThreadPool thread), instantiates
            > and calls MethodD on COM+ class (C2).
            > MethodD of COM+ Class (C2) instantiates and calls MethodE on COM+ class
            > (C3).
            > Finally, methodB of .NET Class (N1) uses static members of .NET Class (N2)
            > to retrieve the results of the "background " processing. These results are
            > passed back to COM+ Class (C1) and ultimately displayed on the ASP page.
            > Note: All COM+ classes are registered within the same COM+ application;
            > and this application is configured as a "Library" application.
            >
            > I believe this sequence of calls results in the following transitions:
            > An IIS worker thread, (running C1), transitions to .NET managed thread,
            > (running N1). I'm not at all clear as to what process owns the ..NET thread.
            > As a result of item#1 a .NET ThreadPool thread, (running N2), transitions to
            > a COM+ thread, (running C2).
            > I'm assuming the same COM+ Thread from item#2 is used to run C3.
            > The COM+ Thread running C2 and C3 completes and transitions back to the .NET
            > ThreadPool thread running N2.
            > Based on a flag exposed as a static member of N2, the "original" ..NET Thread
            > begins accessing static members of N2. (These static members are used to
            > aggregate results across multiple ThreadPool threads.)
            > Finally, the "original" .NET thread transitions back to the IIS worker
            > thread running C1.
            > After modifying Machine.Config such that the "ProcessMod el" tag used the
            > "system" account instead of the "machine" account, I was able to get this
            > working in Debug mode. The modification was required to enable transition #2
            > (listed above). Prior to making this modification an exception was thrown
            > indicating an inability to call COM+ class C2. (Sorry, I don't recall the
            > exact exception.)
            >
            > When I say Debug mode, I'm referring to running the code within the
            > VS.NET and VS6 IDEs and stepping between break points.
            >
            > With everything working in Debug mode, I then attempted to execute the code
            > without debugging. Based on well placed App.LogEvent and EventLog.WriteE ntry
            > calls, it appears that the following is occurring:
            > All calls prior to the calling of COM+ Class C3 appear to be working.
            > The Call to COM+ Class C3 doesn't raise a COM+ error, but the variant
            > returned from this call is empty. During successful execution the resulting
            > variant contains an array with a "UBound" of 5. The real puzzling thing
            > about this situation is that an error with COM+ class C3 should result in a
            > variant containing an array with a "UBound" of 3. There should always be an
            > array returned from COM+ C3!
            > So the questions are as follows:
            > Is it possible that the return values, (which are passed ByRef), aren't
            > being marshalled properly between COM+ Class C2 and COM+ Class C3?
            > Is it possible that the call from COM+ Class C2 to COM+ Class C3 is failing
            > silently? (Placing App.LogEvent calls within COM+ Class C3 requires the
            > involvement of another team.)
            > Is there some security or thread related issue here that I'm just not
            > seeing? And does this underlying issue explain why things work during Debug
            > and fail when not running under an IDE managed thread?
            > Thanks for taking the time to read all of that. :-)
            >
            >[/color]

            Comment

            Working...