简体   繁体   中英

Unexpected result when calling the same web service multiple times simultaneously

I am having a problem when issuing many requests to the same web service operation simultaneously (that is, in many threads).

Each time I call the web service, I log it to the console, so my output is something like

Calling OperationA with paramA = 'A'
Calling OperationA with paramA = 'B'
Calling OperationA with paramA = 'C'
Calling OperationA with paramA = 'D'
...
Calling OperationA with paramA = 'Z'

which shows that I'm calling the same operation with different parameters.

I'm using Fiddler to trace these requests, and I expected to see all of my requests in the order they were issued on the application. But it's all wrong: the requests are all out of order, some requests are issued more than once, and some are not issued at all (that is, my printf says I called it, but Fiddler doesn't show anything).

It seems like the problem is issuing a lot of requests in a short period of time, because if I put a Thread.Sleep(2000) between each call, everything works like a charm.

Is this some kind of expected behavior? Why aren't the requests being queued correctly?

By the way, this is a C# 2.0 client, invoking an AXIS 2.0 secure web service using a proxy class generated by wsdl.exe, and I'm using the asynchronous "begin Operation " and "end Operation " methods in the proxy class to issue the requests.

EDIT: Here's how I'm calling this operation over and over:


foreach(List listOfMyClass1 in  listOfListOfMyClass1)
{
 MyClass2[] webServiceParameter = listOfMyClass1.ToArray();

 // Here I log that I'm calling the operation, and print every element in webServiceParameter

 IAsyncResult ar = wsClient.BeginOperationA(webServiceParameter);

 listOfAsyncResults.Add(ar);

  // System.Threading.Thread.Sleep(2000); --> This solves the problem..
}

foreach(IAsyncResult ar in listOfAsyncResults)
{
 WebServiceResultClass result = wsClient.EndOperationA(ar);
}

I wouldn't expect them to go in any particular order, but each should only occur once.

I'm going to use psychic debugging to try to work out what's wrong though... I suspect you've got a loop like this:

foreach (string input in data)
{
    new Thread(() => CallWebService(input)).Start();
}

This is capturing the loop variable - which is a bad idea . It's easy to fix though:

foreach (string input in data)
{
    string copy = input;
    new Thread(() => CallWebService(copy)).Start();
}

(The previous link will explain what's going on... and here's the second part .)

If that isn't the case, please give us some code - otherwise we're really just guessing.

Ok, so the problem was that old problem of changing a variable that was declared outside the loop on each iteration, and using it inside the loop. I mean, it was somewhat similar to this:

MyClass c = new MyClass();
IList<MyClass> myClassList = new List<MyClass>();
for(int i = 0; i < someInt; i++)
{
    c.SomeProperty = i;
    myClassList.Add(c);
}
// And here every "SomeProperty" is the same for every element in the list, since every element references the same variable.

More specifically, the webServiceParameter array (see the code in the question) is actually assigned to a property of another variable (which was declared outside the loop), and this variable is passed to the service call.

So, when too many calls were made very fast, by the time these calls got dispatched, the array would contain the values from the last iteration, causing the 'repeated requests'.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM