【发布时间】: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