我在同时向同一个Web服务操作发出多个请求时遇到问题(即在许多线程中)。
每次调用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'
表明我用不同的参数调用相同的操作。
我正在使用Fiddler跟踪这些请求,我希望按照应用程序发出的顺序查看我的所有请求。但这一切都是错的:请求都是乱序的,有些请求是多次发出的,有些请求根本没有发出(也就是说,我的printf说我叫它,但Fiddler没有显示任何内容)。
似乎问题是在很短的时间内发出了很多请求,因为如果我在每次通话之间放置一个Thread.Sleep(2000)
,那么一切都像魅力一样。
这是某种预期的行为吗?为什么请求没有正确排队?
顺便说一下,这是一个C#2.0客户端,使用wsdl.exe生成的代理类调用AXIS 2.0安全Web服务,我正在使用异步“begin Operation ”和代理类中的“end Operation ”方法发出请求。
编辑:以下是我一遍又一遍地调用此操作的方法:
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);
}
答案 0 :(得分:3)
我不希望它们按任何特定顺序排列,但每次只能出现一次。
我将使用通灵调试试图解决出错的问题......我怀疑你有这样的循环:
foreach (string input in data)
{
new Thread(() => CallWebService(input)).Start();
}
这是捕获循环变量 - 这是bad idea。虽然很容易解决:
foreach (string input in data)
{
string copy = input;
new Thread(() => CallWebService(copy)).Start();
}
(上一个链接将解释正在发生的事情......以及here's the second part。)
如果不是的情况,请给我们一些代码 - 否则我们真的只是猜测。
答案 1 :(得分:0)
好的,问题是在每次迭代时更改在循环外声明的变量并在循环内使用它的旧问题。我的意思是,它有点类似于:
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.
更具体地说,<MyClass>
数组(参见问题中的代码)实际上是分配给另一个变量的属性(在循环外声明),并且该变量被传递给服务调用。 / p>
因此,当调用太多调用时,在调度这些调用时,数组将包含上次迭代的值,从而导致“重复请求”。