提升异步Web调用的性能

时间:2013-04-05 17:59:16

标签: c# web-services asynchronous

Backgound:我必须拨打1500次网络服务电话,大约需要1.3秒才能完成。 (无法控制此第三方API。)总时间= 1500 * 1.3 = 1950秒/ 60秒=大约32分钟。

我想出了一个很好的解决方案,但它没有成功。 所以我改变了对异步网络电话的调用,认为这会极大地帮助我的结果。

示例代码:

预优化:

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来观察事务的发生,并意识到异步方式并没有像我想象的那样快速发送。

捕获的异步请求 Async requests captured

正常没有优化 Normal no optimization 你可以看到asnyc推得很快然后掉了...... 另请注意,在请求10和11之间花了近3秒钟。

为任务创建线程的开销是否需要几秒钟才能减慢? 注意:我所指的任务是4.5 TAP任务库。

为什么请求不会比这更快。 我被告知我正在打的Apache网络服务器可以容纳200个最大线程,所以我没有看到问题..

我没有清楚地想到这个吗? 在调用Web服务时,异步请求几乎没有什么优势吗? 我有代码错误吗? 任何想法都会很棒。

1 个答案:

答案 0 :(得分:2)

经过多天的搜索,我发现这篇文章解决了我的问题: Trying to run multiple HTTP requests in parallel, but being limited by Windows (registry)

请求没有更快地命中服务器的原因是我的客户端代码也与服务器无关。默认情况下,C#仅允许2个并发请求。 见这里:http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit.aspx

我只是添加了这行代码,然后所有请求都以毫秒为单位。

System.Net.ServicePointManager.DefaultConnectionLimit = 50;

enter image description here