Threads asynchronous, web service synchronous?

M

Marty McDonald

I create and start several threads, each thread executes the same method -
within the method, a web service is invoked. I find that the more threads I
use, the longer it takes for all of the threads to finish. The threads are
asynchronous, correct? And I thought each would be able to use it's own
version of the web service. Am I wrong, does the web service force only one
thread at a time to execute?

Here is code if interested... I'm using NUnit for it.

static Int32 _threadFinished = 0;

[Test]
public void SimulateManyUsers()
{
Int32 howManyUsers = 10;
for (Int32 x = 0; x < howManyUsers; x++)
{
Thread t = new Thread(new ThreadStart(this.UseService));
t.Start();
}

//Give threads a chance to finish
Thread.Sleep(20000);

//Check the results
Assertion.AssertEquals("One or more of the threads did not
finish.",howManyUsers,_threadFinished);

}

private void UseService()
{
DateTime refDate = new DateTime(1998,07,04);
DateTime respDate = new DateTime(2003,06,28);
ArmCalcParameters[] i = new ArmCalcParameters[25];
for (Int32 x = 0; x< i.Length; x++)
{
i[x] = new ArmCalcParameters();
i[x].SR = "16";
i[x].SRMP = 12.32f;
i[x].ReferenceDate = refDate;
i[x].ResponseDate = respDate;
i[x].CalcType = CalculationType.SRMPtoARM;
i[x].TransId = x.ToString();
}

ArmCalcParametersOut[] o = new ArmCalcParametersOut[i.Length];
ArmCalcService svc = new ArmCalcService();
o = svc.CalculateBatch(i);
_threadFinished++;
}
 
S

Scott Allen

Hi Marty:

The more threads you add, the more load there is on your machine and
on the machine with the web service, so some amount of additional time
is expected for each thread you've added. The web service will not
force single threaded execution (unless there is code in the web
service call to force single threaded execution).

Couple observations:

Use Interlocked.Increment(x) from System.Threading for a thread safe
increment on the static variable instead of the postfix increment
operator (x++).

If you use an array of Thread in your program, you could call the Join
method on each Thread instance you've started to make sure the thread
completes its work and terminates.


Hope this helps,
 
S

Scott Allen

Oh, just remember the Increment method of Interlocked takes a ref of
course, otherwise it would be rather useless :)

Interlocked.Increment(ref x)

--s
 
S

Steven Cheng[MSFT]

Hi Marty,

As Scott has mentioned, the ASP.NET webservice won't force only one thread
to service the coming request. How it works is actually the same as how the
ASP.NET web application servcie the web request. It'll use a certain
workerthread in the threadpool to service the coming request. And if multi
requests come at the same time, and the existing pooling threads not
enought, new workerthread will be created and also, there is a
"maxWorkerThreads" in the asp.net's <processModel> setting (in the
machine.config).
#<processModel> element
http://msdn.microsoft.com/library/en-us/cpgenref/html/gngrfProcessmodelSecti
on.asp?frame=true

When the comming requests reach this limitation, new coming request will be
queued until the preceding ones are finished.

Also, in addition to use multi-threads to call webservice asynthronous, we
can also use the SoapHttpClient class's buildin async support to call
webmethod as asynthronous mode. Such as BeginXXX and EndXXX. Here is a
certain tech article discussing on this:

#Asynchronous Web Service Calls over HTTP with the .NET Framework
http://msdn.microsoft.com/library/en-us/dnservice/html/service09032002.asp?f
rame=true

Also, all these approachs are performing asynthronized processing at
clientside. There are also something we can do to perform asynthronous at
serverside. Below is another tech article discussing on this:

#Server-Side Asynchronous Web Methods
http://msdn.microsoft.com/library/en-us/dnservice/html/service10012002.asp?f
rame=true

Further more, I recommend that you perform a simple test to confirm this.
For example, provide such as webmethod which will sleep for serveral
seconds and return the threadId and serverside time to client:
public WSResult WaitingFor(int ms)
{
System.Threading.Thread.Sleep(ms);

WSResult res = new WSResult();
res.ThreadID = AppDomain.GetCurrentThreadId().ToString();
res.TimeTicket = DateTime.Now.ToLongTimeString();

return res;
}

public class WSResult
{
public string ThreadID = "";
public string TimeTicket = "";
}

Then, you can try calling this one via both the following means:
1. Call the webmethod in multthreads synthronously ,just as you do
originally.

2. Call the webmethod asynthronously multi-times in single thread( in a
click event)

You can list all the return results in a listbox to have a look. I've
tested on my side and it confirm that the serverside will use multi
workerthread to processing multi comming request.
Hope all these help. Thanks.

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Get Preview at ASP.NET whidbey
http://msdn.microsoft.com/asp.net/whidbey/default.aspx
 
S

Sami Vaaraniemi

Marty McDonald said:
I create and start several threads, each thread executes the same method -
within the method, a web service is invoked. I find that the more threads I
use, the longer it takes for all of the threads to finish. The threads are
asynchronous, correct? And I thought each would be able to use it's own
version of the web service. Am I wrong, does the web service force only one
thread at a time to execute?

There are a couple things that may cause the asynchronous calls to be queued
up and not execute concurrently.

First, there is client-side limit of at most two simultaneous calls. This is
due to HTTP 1.1 protocol that says that one client should have at most two
HTTP calls in progress to one server. You can change this limit e.g., by
modifying the maxconnection attribute in the connectionManagement element in
application config file.

Second, if the Web service uses ASP.NET session state, then ASP.NET will
serialize calls from one client.

Finally, if the server has no free worker threads, then further requests
will be queued up until a thread becomes available. This is controlled with
the maxWorkerThreads setting.

Regards,
Sami
 
M

Marty McDonald

Thanks to all of you who have replied to my post. All of your information
is very useful and informative! Right now, the client and web service are
both on my machine. I will certainly include your suggestions in my code.
The whole purpose of this is to test the responsiveness of my web service.
I also think that it is better if I test this when the web service is on
another server, which is closer to what it will look like in production.
Thank you all!
--Marty
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top