For Programmers: Free Programming Magazines  


Home > Archive > Microsoft Webservices > April 2006 > Csharp async calls to Web Service that calls C++ :: blocking issue









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Csharp async calls to Web Service that calls C++ :: blocking issue
Brian Parker

2006-04-17, 7:07 pm

I inherited a C++ DLL that I need to remotely call multiple times
asynchronously. What I have developed is:

CSharp web application that makes asynchronous calls to a CSharp Web
Service. The Web Service calls the DLL, which does some heavy
processing, then sends the results back to the CSharp web application.

The problem is that the calls to the DLL in the Web Service are blocking
each other. If I send 10 async requests to the Web Service, debug
statements show that they all reach the call to the DLL within 1/10 of a
second, but only one call to the main method in the C++ DLL will run at
a time. If I stub off the call to the DLL and replace it with something
like a 15 second Sleep, the async Web Service calls all process
asynchronously as expected.

Is there an inherent reason why the DLL won't allow multiple calls to
its main method to run concurrently? Does anyone have a suggestion as
to why this is happening?

-BEP
shumaker@cs.fsu.edu

2006-04-17, 7:07 pm

If the DLL is dealing with any objects that are thread safe, and they
happen to try and access the same object for some reason(perhaps
something static in the DLL that all threads would be sharing) then
they will likely execute one at a time as they take they're turn with
the object.

Mart

2006-04-17, 10:04 pm

What version of C++ is the DLL written in?

Mart

2006-04-18, 7:09 pm

Hi Brian,
[color=darkred]
> What version of C++ is the DLL written in?

Thanks. It's been a couple of years since I've done Visual C++ in
anger, but here's where I'd probably start (sorry if I'm teaching
grandma...):

1 - How has the C++ been compiled? Is it multi threaded or single
threaded?
2 - Is the C++ DLL COM or straight C++?
3 - How, where and by what is the C++ DLL being loaded? Which process
space is it running in? Does the model used allow multi threading or
multiple loading?
4 - Does the C++ have any forced syncrohnisation in it - any clues like
link syncs, mutexs, singleton pattern stuff etc?

I'm not sure about the mechanics of how .NET uses native C++ stuff. Are
there any restrictions in the way this works?

Cheers, Mart.

Mart

2006-04-19, 7:08 pm

Hi Brian,

> Oops, I forgot. It was written in VC++ 6.0 but I made a very minor
> change to some logic in it recently and recompiled in VStudio 2003. Not
> sure if that makes a difference, but though it was worth a mention.


I suspect it might, but I've never tried so I can't be sure. To be on
the safe side, I'd want to compile the C++ using the VS6 C++ IDE to
eliminate this as a potential cause, as this (I am assuming!) is how
the orginial author of the DLL compiled it?

> The DLL itself does threading. Here's a quick overview of what it does:
> I send an array to the DLL. The DLL hits a web page for each member of
> the array and brings back the HTML. It parses the HTML, sticks it in a
> database for my C# program to retrieve, then returns. For each web page
> it hits and reads, it spawns a thread.


I doubt whether the threads that the DLL is spawning internally will be
an issue - this sounds fine so long as there are no obvious design or
implementation features that would be actively holding a thread. I
suspect that the blocking is more likely to be associated with how the
calls into the routine that loops your Array are being managed by the
clients of your DLL (i.e. your C# and COM wapper - see below).

> I'm going to assume it was originally compiled multi-threaded. How can I tell?
> I did searches on LIBC, LIBCMT, and MSVCRT and turned up nothing. I
> don't see where in the IDE I can control the linker options - only how
> to set them via the command-line, a command file, or via the ENV vars.


As far as I remember it's in the Project Setting in the VS6 C++ IDE.
It's been a while, but I think to use Win32 multithreading you need to
set the runtime library to "Multithreaded DLL".

> I'm really not sure.
> 3 - How, where and by what is the C++ DLL being loaded? Which process
> space is it running in? Does the model used allow multi threading or
> multiple loading?
> This is what I have to do to use it:
> I register the DLL using regsrv32
> In VStudio, I go under "Project -> Add Reference" and find it under the
> COM tab - that may answer your previous question.


Yep 3 answers 2! My understanding from what you say is that your C++
DLL is COM compliant.

There is plenty on COM on MSDN if you're uncertain and want to know
more about it (try www.microsoft.com/com). In case you're not aware,
COM (Component Object Model) is a framework that Microsoft introduced
to facilitate interoperability between software components without
those components knowing about each other's internals. COM allows you
to write components in different languages, and, so long as they are
COM-compliant, they can communicate with each other. You may have heard
of OLE and ActiveX? These are technologies within the COM umbrella
framework.

For your managed code (.NET C#) to interoperate with your COM DLL
(C++), a wrapper needs to be constructed which allows your C# to
communicate with your C++. Microsoft suggest using the Type Library
Importer tool to setup a .NET wrapper for a COM component that you wish
to call (see
http://msdn2.microsoft.com/en-US/library/ms173185(VS.80).aspx and
http://msdn2.microsoft.com/en-US/library/zeaxheha(VS.80).aspx for more
details). However, it may be the case that this is being run, and that
a wrapper is being created automatically for you, when you add the
reference to your project in the process you outline above. It's worth
checking that this done correctly!

I'm not sure how the wrappers created to allow you to call the COM
component work, so I don't know whether they will be synchronising
calls or not, preventing multiple loading or multithreading and so on.
Sorry I can't help anymore on this without researching it! :o)

> It uses a few mutexes, but only when it accesses specific web pages, and
> the 2 that use mutexes I'm not using in my testing so that code never
> gets called.
> One other place it uses mutexes is in the error handler. If there's an
> error, it writes it to a log and the mutex is there to stop file errors.


Umm, might be worth following the logic through as best you can to see
whether these are holding something up.

> This is my first time with it. I'm not compiling the C++, I'm just
> hooking into the DLL when my code runs. The DLL is already registered
> in the system and waiting for something like my program to use it.


> I don't think I gave you too many answers to your question, but
> hopefully there's something there that may spark something. I
> appreciate your help.


No problem!

As a suggestion, one way to see whether it's your COM, the COM wrapper
or the C# might be to use write a test ASP classic page to load the COM
DLL and kick off the same COM process. Again it's been a while, but
something like:

<%
Dim myComThingy
myComThingy = Server.CreateObject("MyLib.MyComponent")
myComThingy.DoTheLoopStuff(anArray)
%>

Then call into this ASP Classic page multiple times and see what
happens. You'll need to make sure that the Virtual Directory that the
ASP page is in on IIS is setup to put ASP into a COM+ process rather
than loading it into the IIS process space (set the application
protection to Medium (Pooled) in the Virt Dir properties in IIS5).

If the COM does it's job without holding synching the calls, then
you'll know the COM works and your issue is on the C# or COM wrapper
side. If not, then you know it's the COM.

Hope this helps, Mart.

Mart

2006-04-20, 10:04 pm

Hi Brain,

Ah, thought it might be so! Free threading might be you best option.

Apartment threading is where you have a number of "apartments" which
each run a single thread (imagine the OS as a block of apartments, in
each of which runs a seperate single thread). Apartment threaded COM
objects exist within an "apartment". This means that they are
single-threaded, but in the system at large (i.e. across many
apartments) a form of multithreading can happen because different
threads will be running through different instances of a COM component
in different apartments.

This also is the restriction of apartment threading: An instance of a
COM object (i.e. instance of your C++ DLL) will be running in a single
apartment, and will therefore be single threaded in itself, not
multithreaded. This also means that calls between COM objects sometimes
have to be marshalled across threads (i.e. between apartments).

Free threading is true multithreading, and means that multiple threads
can be running through one COM object. This is your best choice if you
want to have one instance of your COM object being accessed
simultaneously.

The divantage of free threading is that you have to make sure your
COM object is thread-safe (which, I assume, it is). In apartment
threading this is not necessary, since a *different* instance of your
COM component will be running singularly in *different* apartments;
therefore is single-threaded in itself and does not need to be
thread-safe.

Again, I expect google and MSDN can explain more than me!

Cheers, Mart.

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com