У меня есть метод в приложении ASP.NET, на выполнение которого уходит довольно много времени. Вызов этого метода может происходить до 3 раз в течение одного пользовательского запроса, в зависимости от состояния кеша и параметров, которые пользователь предоставляет. Каждый вызов занимает около 1-2 секунд. Сам метод является синхронным вызовом службы и нет возможности переопределить реализацию.
Таким образом, синхронный вызов службы выглядит примерно так:
public OutputModel Calculate(InputModel input)
{
// do some stuff
return Service.LongRunningCall(input);
}
И использование метода (обратите внимание, что вызов метода может происходить более одного раза):
private void MakeRequest()
{
// a lot of other stuff: preparing requests, sending/processing other requests, etc.
var myOutput = Calculate(myInput);
// stuff again
}
Я пытался изменить реализацию со своей стороны, чтобы обеспечить одновременную работу этого метода, и вот к чему я до сих пор пришел.
public async Task<OutputModel> CalculateAsync(InputModel input)
{
return await Task.Run(() =>
{
return Calculate(input);
});
}
Использование (часть кода "делать другое" выполняется одновременно с вызовом службы):
private async Task MakeRequest()
{
// do some stuff
var task = CalculateAsync(myInput);
// do other stuff
var myOutput = await task;
// some more stuff
}
У меня следующий вопрос. Правильно ли я использую для ускорения выполнения в приложении ASP.NET или выполняю ненужную работу, пытаясь запустить синхронный код в асинхронном режиме? Может ли кто-нибудь объяснить, почему второй подход не подходит для ASP.NET (если это действительно не так)? Кроме того, если такой подход применим, нужно ли мне вызывать такой метод асинхронно, если это единственный вызов, который мы могли бы выполнить в данный момент (у меня есть такой случай, когда больше ничего не нужно делать в ожидании завершения)?
Большинство статей в сети по этой теме посвящены использованию async-await
подхода с кодом, который уже предоставляет awaitable
методы, но это не мой случай. Вот- это хорошая статья, описывающая мой случай, в которой не описывается ситуация с параллельными вызовами, отказываясь от возможности обернуть вызов синхронизации, но, на мой взгляд, моя ситуация как раз является поводом для этого.
Заранее благодарим за помощь и советы.
Task.Run
, содержимое запускается в другом потоке, который берется из пула потоков. Тогда вообще нет необходимости переносить блокирующие вызовы (например, мой вызов службы) вRun
s, потому что они всегда будут использовать один поток каждый, который будет заблокирован во время выполнения метода. В такой ситуации единственное преимущество, которое остаетсяasync-await
в моем случае, - это одновременное выполнение нескольких действий. Пожалуйста, поправьте меня, если я ошибаюсь.