Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / September 2005

Tip: Looking for answers? Try searching our database.

COM and Threading problem(I think)

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Brook - 22 Sep 2005 12:28 GMT
I have a VB.net application which creates two threads (A&B). In Thread A I
create an instance of an object contained in a COM dll which performs a
lengthy search operation. In Thread B i create an instance of the same
object in the same COM dll but i perform a short search. As i'm using
multiple threads and i believe the underlying code to be thread safe, I
cannot understand why Threads A & B return their results at the same time.
Rather than the short search returning results after a couple of seconds and
the long search returning results a couple of minutes later.

Any ideas?
ta,
Andrew
Phil Wilson - 22 Sep 2005 21:29 GMT
It looks like you have a single-threaded apartment (STA) somewhere. You app
itself is probably STA by default.

http://msdn.microsoft.com/msdnmag/issues/04/06/BasicInstincts/
Signature

Phil Wilson [MVP Windows Installer]
----

>I have a VB.net application which creates two threads (A&B). In Thread A I
> create an instance of an object contained in a COM dll which performs a
[quoted text clipped - 9 lines]
> ta,
> Andrew
Brook - 23 Sep 2005 09:29 GMT
Thanks Phil,

I tried registerimg my COM component with COM+ and in the properties of my
objects it mentions Single Threaded Apartment. So I guess if I want to be
able run two instances of the COM dll totally independantly I have to
recompile/change the objects somehow. I guess a little research into MTA is
in order!

Andrew

> It looks like you have a single-threaded apartment (STA) somewhere. You app
> itself is probably STA by default.
[quoted text clipped - 13 lines]
> > ta,
> > Andrew
TDC - 23 Sep 2005 13:25 GMT
You can set the threading apartment in the Project Propeties of you VB6
project.

Tom
Brook - 23 Sep 2005 17:00 GMT
Hi Tom,

It's a VB.Net application rather than VB6 - I had a look in the project
properties but was unable to find any apartment related options. I found out
that when I create the two threads i can set the ApartmentState property on
each one to be MTA. Unfortunately this didn't fix my problem. I read on the
MSDN that regardless of what ApartmentState you choose it will adopt the one
from the COM component (if i understood it correctly). Unfortunately I have
no idea how to change the COM component objects so they run in MTA.

ta,
Andrew

> You can set the threading apartment in the Project Propeties of you VB6
> project.
>
> Tom
Willy Denoyette [MVP] - 24 Sep 2005 17:10 GMT
What language did you use to author the COM dll?
If it's VB6, make sure the threading mode is set to "apartment" and not
"single" in your project properties.
However, If the threading mode is apartment, your problem lays somewhere
else, are you sure the COM object doesn't call into a resource that
serializes it's accesses?

Willy.

> Hi Tom,
>
[quoted text clipped - 18 lines]
>>
>> Tom
Brook - 26 Sep 2005 10:17 GMT
Hi,

The COM dll is written in C++.Net. The dll is built with build option \Md
which it says is multi-threaded.

It does access a common file (for reading purposes). I'm beginning to think
that it containing single thread apartment objects is ok, the COM dll itself
does not use threads although it is thread safe. Because of this, no
cross-thread communication is required.

thanks,
Andrew

> What language did you use to author the COM dll?
> If it's VB6, make sure the threading mode is set to "apartment" and not
[quoted text clipped - 27 lines]
> >>
> >> Tom
Robert Jordan - 26 Sep 2005 10:30 GMT
> Hi,
>
> The COM dll is written in C++.Net. The dll is built with build option \Md
> which it says is multi-threaded.

/Md doesn't make your COM object beeing free threaded. Nor it makes your
COM object completely thread safe.

> It does access a common file (for reading purposes). I'm beginning to think
> that it containing single thread apartment objects is ok, the COM dll itself
> does not use threads although it is thread safe. Because of this, no
> cross-thread communication is required.

Set the apartment state of your threads to ApartmentState.STA
before running them:

Thread t = new Thread(new ThreadStart(ThreadProc));
t.ApartmentState = ApartmentState.STA;
t.Start()

void ThreadProc()
{
  // create and use the COM object.
}

Rob
Brook - 26 Sep 2005 10:57 GMT
Thanks Rob! Success.

Setting the ApartmentState of my threads to be STA worked. This has me
highly perplexed. The original problem context involved remoting - a remote
service is waiting for requests and creating instance of the COM object to
serve them. I thought it wasn't a remoting/service issue so i re-created the
problem using a desktop app and multiple threads. Now I need to work out how
to configure the remoting to use STAs, but since the remoting layer provides
the threading for me i've no idea how to configure it in the same way I
configured the desktop app. Looks like this may have turned into a remoting
issue...

thanks,
Andrew

> > Hi,
> >
[quoted text clipped - 22 lines]
>
> Rob
Robert Jordan - 26 Sep 2005 11:16 GMT
Hi Andrew,

> Thanks Rob! Success.
>
[quoted text clipped - 7 lines]
> configured the desktop app. Looks like this may have turned into a remoting
> issue...

Use the same "trick": create a new thread from within
your remoted method:

public void SomeMethodExposedWithRemoting (...)
{
  Thread t = new ...
  t.ApartmentState = ApartmentState.STA;
  t.Start();
  Thread.Sleep(0); // give up time slice
  t.Join();
}

void ThreadProc ()
{
  ...
}

You may detect, that there is no way to pass some
arguments to the thread proc. Use or extend this class:

    public delegate void ContextThreadStart(object state);

    public class ContextThread {

        public Thread Thread {
            get {
                return thread;
            }
        }
        readonly Thread thread;
        readonly ContextThreadStart start;
        readonly object state;

        public ContextThread(ContextThreadStart start, object state) {
            this.start = start;
            this.state = state;
            this.thread = new Thread(new ThreadStart(ThreadProc));
        }

        public void Start() {
            thread.Start();
        }

        void ThreadProc() {
            start(state);
        }
    }

Rob
Brook - 27 Sep 2005 09:33 GMT
Hi Rob,

Thanks for the suggestion. I've made further progress with this problem.
First of all I need to mention that my COM component isn't written in
C++.Net! It's just plain old C++ i think.

I was keen on solving this problem without having to write additional
threading code.

Yesterday I found the code in my COM dll source which specified what type of
apartment the objects would use - i have changed this from
threading("apartment")

to

threading("free")

It has fixed my problem for the moment, but I will have to complete thorough
testing given that i don't fully understand the changes i've made. I suppose
i'm lucky that I have the source my my COM dll to play around with :) Thanks
everyone.

Andrew

> Hi Andrew,
>
[quoted text clipped - 59 lines]
>
> Rob
Robert Jordan - 27 Sep 2005 11:35 GMT
Hi Andrew,

> Thanks for the suggestion. I've made further progress with this problem.
> First of all I need to mention that my COM component isn't written in
> C++.Net! It's just plain old C++ i think.

BTW, C++.Net is still able to create plain "old" unmanaged
COM components. You can even import the old project, if it
is a VC 6.0 project.

> I was keen on solving this problem without having to write additional
> threading code.
[quoted text clipped - 6 lines]
>
> threading("free")

That's definitely the best way.

> It has fixed my problem for the moment, but I will have to complete thorough
> testing given that i don't fully understand the changes i've made. I suppose
> i'm lucky that I have the source my my COM dll to play around with :) Thanks
> everyone.

If you take care to create the COM object in each method,
that gets called by the remoting infrastructure, you shouldn't
encounter many problems. Review the C++ code an assure that
there are no static members.

Rob

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.