.NET HTTPClient异步限制

Dom*_*nik 7 .net c# async-await dotnet-httpclient

我有一个小的.Net 4.5 C#应用程序,它从数据源读取信息,然后将此信息推送到一个带有简单控制器的.NET 4.5 Web API站点的网站.控制器接收数据并将其放入数据库.

以下对我有用,只要应用程序可以读取它就可以写入并且所有内容都在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());
        }
    }
Run Code Online (Sandbox Code Playgroud)

以下不起作用.它发布了大约一千多条记录,然后出现了一些错误,所有错误都是"任务被取消",但是大约10秒后它恢复处理:

    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());
        }
    }
Run Code Online (Sandbox Code Playgroud)

完整的错误是:

    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
Run Code Online (Sandbox Code Playgroud)

有什么快速解决方法吗?从我可以告诉它的东西,线程,套接字,谁知道:-)

任何指针都会受到赞赏,我很乐意让它工作,因为你可以想象同步执行POST比异步慢得多.

为了确保它不是我的机器,本地防病毒或网络,我尝试了W2k8 R2服务器,Windows 7虚拟客户桌面(新版本)和Windows 8机器,结果相同.

更多信息:我已经通过LAN连接以及较小的数据集(10,000条记录)和DefaultConnectionLimit 100的部分成功进行了测试.但是,在具有500,000条记录的生产中,当通过Internet发布到远程服务器时(仍然很低)延迟25ms-50ms)我没有取得任何成功.

在此先感谢任何帮助:-)

Dom*_*nik 8

好的,我现在有工作.最重要的是微调服务器端的客户端设置.根据我是在本地还是通过Internet运行测试,这些设置有所不同.

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

    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();
            }
        }));
    }
Run Code Online (Sandbox Code Playgroud)

我在控制台应用程序的顶部声明了以下内容:

    private static List<Task> allTasks = new List<Task>();
    private static SemaphoreSlim throttler;
Run Code Online (Sandbox Code Playgroud)

在我的循环开始之前,我有以下内容,更改了变量以确保它全部工作:

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

    throttle = new SemaphoreSlim(initialCount: _MaxQueue);
Run Code Online (Sandbox Code Playgroud)

作为指南,对于基于Internet的交易,以下内容适用于我:

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

对于我的局域网测试,我可以运行默认连接和初始计数值更高而没有问题,这是我猜的:-)

最后,在我的外观之外,我有以下内容以确保我不会杀死在执行结束时仍在运行的任何任务:

     await Task.WhenAll(allTasks);
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!