【问题标题】:Beginning a new, quick http request while a long running one is in progress在长时间运行的请求正在进行时开始一个新的、快速的 http 请求
【发布时间】:2019-11-02 04:44:53
【问题描述】:

根据标题,我有一个长时间运行的 GET 请求正在执行,并且需要执行小而快速的请求,同时等待长请求的响应。不幸的是,快速请求似乎必须等待长时间运行的请求才被允许执行。如果它有助于可视化,这是一个 Web 服务,它接受请求,它正在中继到另一个 Web 服务并将结果返回给它的客户端,因此无论何时客户端触发它们,它们几乎都可以进入。

我尝试过使用相同的 httpclient,不同的 httpclients,我尝试过更改 HttpClientHandler.MaxConnectionsPerServer 和 ServicePointManager.DefaultConnectionLimit,但似乎没有任何效果。我已经看到使用 WhenAll 等的解决方案,但这在这里不起作用,因为小请求是在长时间运行的请求早就开始和“WhenAll-ed”之后进来的。

我创建了一个测试应用程序,它是一个简单的 windows 窗体来解决这个问题,它看起来很像这样(通过按钮单击来模拟接收到的 Web 请求):

    CookieContainer CookieContainer = null;
    MyClient myClient;

    public Form1()
    {
        InitializeComponent();
        ServicePointManager.DefaultConnectionLimit = 10;

        myClient = new MyClient(ref CookieContainer);
    }

    private async void button1_Click(object sender, EventArgs e)
    {            
        bool success = await myClient.GetStockItemTables();
        this.label1.Text = success.ToString();
    }

    private async void button2_Click(object sender, EventArgs e)
    {            
        bool success = await myClient.GetGiftCardBalance();
        this.label2.Text = success.ToString();
    }


class MyClient
{
    string EndpointURL = @"XXX";
    private HttpClient Client;
    private HttpClientHandler ClientHandler;       

    public MyClient(ref CookieContainer cookieContainer)
    {
        try
        {
            bool loginRequired = false;                

            if (cookieContainer == null)
            {
                loginRequired = true;
                cookieContainer = new CookieContainer();
                //clientHandler = new HttpClientHandler { UseCookies = true, CookieContainer = new CookieContainer() };
            }

            ClientHandler = new HttpClientHandler { UseCookies = true, CookieContainer = cookieContainer, MaxConnectionsPerServer = 10 };

            Client = new HttpClient(ClientHandler)
            {
                BaseAddress = new Uri(EndpointURL),
                DefaultRequestHeaders =
                {
                    Accept = {MediaTypeWithQualityHeaderValue.Parse("text/json")}
                },
                Timeout = TimeSpan.FromHours(1)
            };

            if (loginRequired)               
                DoLogin(false);                
        }
        catch (Exception ex)
        {

        }
    }
    public async Task<bool> LongRunningRequest()
    {

        try
        {                
            var result = await Client.GetAsync(EndpointURL + "YYY");

            return true;
        }
        catch (Exception ex)
        {
            return false;
        }
    }
    public async Task<bool> QuickRequest()
    {

        try
        {                
            var result = await Client.GetAsync(EndpointURL + "ZZZ");

            return true;
        }
        catch (Exception ex)
        {
            return false;
        }
    }
}

CookieContainer 被传入/传出以维护登录信息和排除登录方法,因为它有效并且与问题无关。单击按钮 1 然后单击按钮 2 的结果是代码“卡”在快速请求“PostAsync”上,直到长请求“GetAsync”完成。如果每个调用都使用它自己的 MyClient 而不是共享全局调用,则结果相同。帮忙?

【问题讨论】:

  • await 在做什么?
  • 查看答案。这是阻止并发请求的 Web 服务。

标签: c# httpclient


【解决方案1】:

所以看起来不是我或代码。我正在使用的 Web 服务阻止来自同一会话的并发请求。将快速请求更改为仅从谷歌“获取”会立即评估并且不会像预期的那样被阻止。看起来解决方案是为这些快速调用创建第二个会话,以便在我们处于长请求中间时它们不会被阻止。

【讨论】:

    猜你喜欢
    • 2011-01-12
    • 2016-05-24
    • 2017-10-05
    • 2012-08-20
    • 2012-12-14
    • 2012-02-16
    • 2011-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多