简体   繁体   English

同时调用同一Web服务多次时出现意外结果

[英]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). 同时向同一Web服务操作(即,在多个线程中)发出多个请求时出现问题。

Each time I call the web service, I log it to the console, so my output is something like 每次调用Web服务时,都会将其记录到控制台,因此输出类似于

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. 我正在使用Fiddler来跟踪这些请求,我希望可以按照在应用程序上发出的顺序查看所有请求。 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). 但这全都错了:请求全部乱了,有些请求发出了不止一次,有些根本没有发出(也就是说,我的printf说我叫了它,但是Fiddler没有显示任何东西)。

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. 似乎问题在于在短时间内发出了很多请求,因为如果我在每次调用之间放置Thread.Sleep(2000) ,那么一切都会像个符咒。

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. 顺便说一句,这是一个C#2.0客户端,它使用wsdl.exe生成的代理类来调用AXIS 2.0安全Web服务,而我正在代理类中使用异步的“开始操作 ”和“结束操作 ”方法来发出请求。

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. 更具体地说,实际上将webServiceParameter数组(请参见问题中的代码)分配给另一个变量的属性(该变量在循环外部声明),并将此变量传递给服务调用。

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'. 因此,当非常快地进行太多调用时,在调度这些调用时,数组将包含上次迭代的值,从而导致“重复请求”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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