.NET异步的HTTPClient限制 [英] .NET HTTPClient Asynchronous Limitations

查看:336
本文介绍了.NET异步的HTTPClient限制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个小的.Net 4.5 C#应用程序,它从一个数据源读取信息,并推动该信息网站是一个.NET 4.5的Web API网站用一个简单的控制。该控制器接收数据,并将其放入数据库中。

I have a small .Net 4.5 C# app which reads information from a data source and then pushes this information to a web site which is a .NET 4.5 Web API site with a simple controller. The controller receives the data and puts it into a database.

我下面的工作,以最快的速度应用程序可以读取它可以写,一切都结束了在DB:

The following works for me, as fast as the application can read it can write and everything ends up in the DB:

    public static void PostDataToWebApi(MyDataClass tData)
    {
        HttpResponseMessage s = null;

        try
        {
            s = client.PostAsJsonAsync("/api/Station/Collector", tData).Result;
            s.EnsureSuccessStatusCode();
        }
        catch (Exception e)
        {
            Console.WriteLine("ERROR (ClientPost): " + e.ToString());
        }
    }

以下不工作。它张贴关于一千多元的记录,然后来了一个数字错误的所有消息任务被取消的,但约10秒后继续处理:

The following does NOT work. It POSTs about a thousand-odd records and then comes up with a number of errors all with the message "a task was canceled", but then after about 10 seconds it resumes processing:

    public static async void PostDataToWebApi(MyDataClass tData)
    {
        HttpResponseMessage s = null;

        try
        {
            s = await client.PostAsJsonAsync("/api/Station/Collector", tData);
            s.EnsureSuccessStatusCode();
        }
        catch (Exception e)
        {
            Console.WriteLine("ERROR (ClientPost): " + e.ToString());
        }
    }

完整的错误是:

The full error is:

    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
    at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
    at IICE_DataCollector_Remote.Program.<PostDataToWebApi>d__7.MoveNext() in e:\Users\TestUser.TEST\Documents\Visual Studio 2012\Projects\Test_App-trunk\TestCollector\Program.cs:line 475

任何快速修复呢?从我可以告诉它运行出来的东西,线程,插座,谁知道: - )

Any quick fixes for this? From what I can tell it runs out of something, threads, sockets, who knows :-)

任何指针将AP preciated,我很想得到这个工作,你可以想像做POST同步比异步慢得多。

Any pointers would be appreciated, I'd love to get this working, as you can imagine doing the POST synchronously is considerably slower than asynchronously.

只是可以肯定那不是我的机器,当地的防病毒软件或网络我已经尝试了W2K8 R2服务器,Windows 7虚拟客户桌面(鲜生成)和Windows 8的计算机上为好,用相同的的结果。

Just to be sure it wasn't my machine, local anti-virus or network I have tried on a W2k8 R2 server, a Windows 7 virtual guest desktop (fresh build) and a Windows 8 machine as well, with the same result.

更多信息:我已经测试这从一个较小的数据集(10000条记录)LAN连接,并为100。DefaultConnectionLimit部分成功,但是,在生产50万条记录,发帖时在互联网上的远程服务器(仍低时延25毫秒,50毫秒),我还没有成功。

More Info : I have tested this with partial success from a LAN connection with a smaller data set (10,000 records), and a DefaultConnectionLimit of 100. But, in production with 500,000 records, when posting to a remote server across the Internet (still low latency 25ms-50ms) I have not had any success.

在此先感谢您的帮助: - )

Thanks in advance for any help :-)

推荐答案

好吧,我现在的工作。最重要的事情是微调在客户端的设置,对于服务器。这取决于我在本地或在互联网上运行测试,这些设置都是不同的。

Ok, I have it working now. The biggest thing was to fine-tune the settings on the client end, for the server. These settings were different depending on whether I was running a test locally or over the Internet.

我的PostDataToWebApi方法现在看起来是这样的:

My "PostDataToWebApi" method now looks like this:

    public static async void PostDataToWebApi(MyDataClass tData)
        {

        await throttler.WaitAsync();
        allTasks.Add(Task.Run(async () =>
        {

            try
            {
                var s = await client.PostAsJsonAsync("/api/Station/Collector", tData).ConfigureAwait(false);
            }
            catch (Exception e)
            {
                Console.WriteLine("ERROR (ClientPost): " + e.ToString());
            }
            finally
            {
                throttler.Release();
            }
        }));
    }

我已经在我的控制台应用程序顶部的以下声明:

I have the following declared at the top of my console application:

    private static List<Task> allTasks = new List<Task>();
    private static SemaphoreSlim throttler;

我的循环开始之前,我有以下的,与变量变化,以确保它所有作品:

Before my loop starts I have the following, with the variables changed to make sure it all works:

    ServicePointManager.DefaultConnectionLimit = _DefaultConnections;
    ServicePointManager.MaxServicePointIdleTime = _MaxIdleTime;
    ServicePointManager.Expect100Continue = false;
    ServicePointManager.CheckCertificateRevocationList = false;

    throttle = new SemaphoreSlim(initialCount: _MaxQueue);

作为指导,为基于互联网的交易我了以下工作:

As a guide, for an Internet based transaction the following works for me:

  1. 默认连接:24
  2. 最大空闲时间:400
  3. SemaphoreSlim初始值:50

有关我的局域网内测试,我可以同时运行在默认的连接和初始计数值,而不会出现问题,这是可以预料我想: - )

For my LAN test I could run both the default connections and the initial count values higher without a problem, which is to be expected I guess :-)

最后,就在我的样子我有以下的,以确保我不杀我的执行运行结束时仍在运行的任何任务:

Finally, just outside my look I have the following to make sure I don't kill any tasks still running at the end of my execution run:

     await Task.WhenAll(allTasks);

希望这有助于!

Hope this helps!

这篇关于.NET异步的HTTPClient限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆