【发布时间】:2018-08-27 15:00:53
【问题描述】:
背景:
我们构建了一个与 ASP.NET Web API 2 后端通信的 React SPA,.NET Framework 4.6.1。在我们的初始加载中,我们发出两个单独的请求来加载数据。在加载大量数据时,我们注意到在应用程序中发出 API 请求时,它们都比在 Postman 中单独尝试请求时慢得多。
原文:
示例结构,fetch当然使用我们的API:
fetch('http://example.com/movies.json')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(JSON.stringify(myJson));
});
fetch('http://example.com/otherMovies.json')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(JSON.stringify(myJson));
});
示例 C# API 方法:
[HttpGet]
[Route("{bsid}/{caseId}")]
public IHttpActionResult GetRenewalCycleForCustomer(string bsid, int caseId)
{
var customerNumbers = GetCustomerNumbers();
var userId = HttpContext.Current.User.Identity.GetUserId<int>();
var user = identityDb.Users.Find(userId);
var customerNumbers = user.ApplicationUserCustomerNumbers.Select(x => new CustomerNumberKey() { bsid = x.CustomerNumber.bsid, NameNo = x.CustomerNumber.NameNo }).ToList();
var db = new DbContext();
var caseService = new CaseService(db);
var portfolioTabViewModel = caseService.GetPortfolioTabViewModelForCustomer(bsid, caseId, customerNumbers);
return Ok(portfolioTabViewModel);
}
操作系统是 Windows 10 Pro,IIS 应该能够根据 Internet 处理 10 个并发连接。无论如何都没有关系,因为我们将它作为 Windows Server 托管在 Azure 上,并且在那里我们有相同的响应时间。也试过应用服务,结果是一样的。
使用 Postman Runner 同步测试响应时间
两个 Postman Runner 实例同时运行:
其他说明:
似乎与硬件无关,因为无论是否同时发出请求,CPU、内存和磁盘都不会受到影响。
我们可以做些什么来解决这个问题?
似乎并行运行的非异步方法:
https://stackoverflow.com/a/26737847/3850405
一些线程建议会话状态,但我在Web.config 中找不到任何引用,这不是我启用的任何内容。搜索 HttpContext.Current.SetSessionStateBehavior 得到 0 个结果。
https://stackoverflow.com/a/26172317/3850405
Windows 10 资源:
https://serverfault.com/a/800518/293367
https://forums.asp.net/t/2100558.aspx?concurrent+connections+on+windows+pro+10+IIS
更新异步和 IIS:
好像和async或者IIS没有关系,用下面的方法测试并发请求。并发的慢请求似乎取决于其他东西。
异步:
[HttpGet]
[Route("{bsid}/{caseId}")]
public async Task<IHttpActionResult> Get(string bsid, int caseId)
{
await Task.Delay(3000);
return Ok();
}
同步:
[HttpGet]
[Route("{bsid}/{caseId}")]
public IHttpActionResult Get(string bsid, int caseId)
{
Thread.Sleep(3000);
return Ok();
}
更新 2:具有异步和同步调用的数据库:
似乎也不是数据库调用。使用Include 进行测试,调用的速度相似,尽管异步调用要慢得多。
异步:
[HttpGet]
[Route("{bsid}/{caseId}/async")]
public async Task<IHttpActionResult> GetAsync(string bsid, int caseId)
{
var db = new DbContext();
var deviations = await db.RenewalCycles.Where(x => x.Deviations.Any())
.Include(cycle => cycle.TPCase.CaseNames.Select(caseName => caseName.TPName))
.Include(cycle => cycle.TPCase.CaseNames.Select(caseName => caseName.TPNameType))
.Include(cycle => cycle.TPCase.GoodsAndServicesDescriptions)
.Include(cycle => cycle.TPCase.RelatedCases.Select(relatedCase => relatedCase.TPCaseRelation))
.Include(cycle => cycle.TPCase.RelatedCases.Select(relatedCase => relatedCase.TPCountry))
.ToListAsync();
return Ok();
}
同步:
[HttpGet]
[Route("{bsid}/{caseId}")]
public IHttpActionResult Get(string bsid, int caseId)
{
var db = new DbContext();
var deviations = db.RenewalCycles.Where(x => x.Deviations.Any())
.Include(cycle => cycle.TPCase.CaseNames.Select(caseName => caseName.TPName))
.Include(cycle => cycle.TPCase.CaseNames.Select(caseName => caseName.TPNameType))
.Include(cycle => cycle.TPCase.GoodsAndServicesDescriptions)
.Include(cycle => cycle.TPCase.RelatedCases.Select(relatedCase => relatedCase.TPCaseRelation))
.Include(cycle => cycle.TPCase.RelatedCases.Select(relatedCase => relatedCase.TPCountry))
.ToList();
return Ok();
}
【问题讨论】:
-
@PeterB 不,与异步无关。这是由于并发请求,同步代码中也存在问题。可以在原始示例中看到。
标签: c# asp.net iis concurrency iis-10