Фон:
Мы создали React SPA, который взаимодействует с серверной частью ASP.NET Web API 2. 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 должен поддерживать 10 одновременных подключений в соответствии с Интернетом. В любом случае это не имеет значения, потому что мы размещаем его в Azure как Windows Server и у нас там одинаковое время отклика. Пробовал также и службу приложений, и результат был тот же.
Тестирование времени отклика синхронно с почтальоном Runner
Два экземпляра Бегуна Почтальона, идущие одновременно:
Другие примечания:
Не похоже, что аппаратное обеспечение связано с тем, что ЦП, память и диск не заслуживают внимания, если запросы выполняются одновременно или нет.
Что мы можем сделать, чтобы это исправить?
Не асинхронный метод, который запускается параллельно:
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
Обновление Async и IIS:
Похоже, это не связано с асинхронностью или 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();
}