C# 提高异步web调用的性能
Backgound:我必须调用一个web服务调用1500次,大约需要1.3秒才能完成。(无法控制此第三方API。)总时间=1500*1.3=1950秒/60秒=32分钟 我想出了一个我认为是好的解决方案,但结果并没有那么好。 因此,我将调用更改为异步web调用,认为这将极大地帮助我的结果,但事实并非如此 示例代码: 预优化:C# 提高异步web调用的性能,c#,web-services,asynchronous,C#,Web Services,Asynchronous,Backgound:我必须调用一个web服务调用1500次,大约需要1.3秒才能完成。(无法控制此第三方API。)总时间=1500*1.3=1950秒/60秒=32分钟 我想出了一个我认为是好的解决方案,但结果并没有那么好。 因此,我将调用更改为异步web调用,认为这将极大地帮助我的结果,但事实并非如此 示例代码: 预优化: foreach (var elmKeyDataElementNamed in findResponse.Keys) { var getRequest = new
foreach (var elmKeyDataElementNamed in findResponse.Keys)
{
var getRequest = new ElementMasterGetRequest
{
Key = new elmFullKey
{
CmpCode = CodaServiceSettings.CompanyCode,
Code = elmKeyDataElementNamed.Code,
Level = filterLevel
}
};
ElementMasterGetResponse getResponse;
_elementMasterServiceClient.Get(new MasterOptions(), getRequest, out getResponse);
elementList.Add(new CodaElement { Element = getResponse.Element, SearchCode = filterCode });
}
var tasks = findResponse.Keys.Select(elmKeyDataElementNamed => new ElementMasterGetRequest
{
Key = new elmFullKey
{
CmpCode = CodaServiceSettings.CompanyCode,
Code = elmKeyDataElementNamed.Code,
Level = filterLevel
}
}).Select(getRequest => _elementMasterServiceClient.GetAsync(new MasterOptions(), getRequest)).ToList();
Task.WaitAll(tasks.ToArray());
elementList.AddRange(tasks.Select(p => new CodaElement
{
Element = p.Result.GetResponse.Element,
SearchCode = filterCode
}));
通过优化:
foreach (var elmKeyDataElementNamed in findResponse.Keys)
{
var getRequest = new ElementMasterGetRequest
{
Key = new elmFullKey
{
CmpCode = CodaServiceSettings.CompanyCode,
Code = elmKeyDataElementNamed.Code,
Level = filterLevel
}
};
ElementMasterGetResponse getResponse;
_elementMasterServiceClient.Get(new MasterOptions(), getRequest, out getResponse);
elementList.Add(new CodaElement { Element = getResponse.Element, SearchCode = filterCode });
}
var tasks = findResponse.Keys.Select(elmKeyDataElementNamed => new ElementMasterGetRequest
{
Key = new elmFullKey
{
CmpCode = CodaServiceSettings.CompanyCode,
Code = elmKeyDataElementNamed.Code,
Level = filterLevel
}
}).Select(getRequest => _elementMasterServiceClient.GetAsync(new MasterOptions(), getRequest)).ToList();
Task.WaitAll(tasks.ToArray());
elementList.AddRange(tasks.Select(p => new CodaElement
{
Element = p.Result.GetResponse.Element,
SearchCode = filterCode
}));
小样本示例:
所以为了便于测试,我对40条记录进行了一次较小的抽样,这花了60秒,没有优化,而优化只花了50秒。我本以为会接近30岁或更好
我使用wireshark监视事务的完成,并意识到异步方式发送的速度不如我想象的那样快
捕获的异步请求
正常无优化
你可以看到asnyc推得很快,然后下降。。。
还请注意,在请求10和11之间,它花费了将近3秒的时间
为任务创建线程的开销是否慢到需要几秒钟?
注意:我指的任务是4.5 TAP任务库
为什么请求不会比这来得快呢。
有人告诉我,我正在使用的Apache web服务器最多可以容纳200个线程,所以我看不出有任何问题
我是不是想得不清楚?
调用web服务时,异步请求是否没有什么好处?
我有密码错误吗?
任何想法都会很好。经过几天的搜索,我发现这篇文章解决了我的问题: 请求没有更快地到达服务器的原因也是由于我的客户端代码,与服务器无关。默认情况下,C#只允许2个并发请求。 请看这里: 我只是简单地添加了这行代码,然后所有请求都在毫秒内完成
System.Net.ServicePointManager.DefaultConnectionLimit = 50;
在执行一个调用所需的1.3秒内,有多少时间是在服务器上实际执行的?如果服务器执行工作需要1.2秒,并且存在资源限制,则异步可能不会产生任何影响。请理解,服务器可能总是需要1.3秒,但如果请求同时运行,则它应该需要更多的时间。正确吗?这取决于资源限制。有些东西不能从并发中获益,有些东西甚至会因此而受损。这取决于导致服务器花费1.3秒的原因。它可能不会从并发性中受益。忘记在服务器上运行所需的时间吧,我关心的是服务器上的请求。有时服务器没有收到我的请求,例如请求10和11,它花了将近3秒钟到达服务器。我甚至不看服务器的响应,这需要多长时间。我只是希望我能在15秒内发送所有请求,然后在任何时候都能得到响应。除了总的并发请求数之外,大概对单个IP地址的并发请求数有限制。也就是说,虽然服务器可能能够同时处理200个请求,但它不一定允许任何一个客户端使用所有这些请求。如果是这样的话,个人对web服务器进行DDOS攻击是很简单的。那么,您在提到的帖子中是否也对注册表进行了更改,或者您是否只更改了System.Net.ServicePointManager.DefaultConnectionLimit?不需要对注册表进行更改,这完全是针对IE的(如果我没记错的话),而这并没有解决这个问题。