Альтернатива Task.Run

У меня есть программа ASP.NET MVC 4, и я написал следующий код, в котором хотел сделать метод Results() асинхронным:

public async Task<ActionResult> Results()
{
  var result1 = SomeMethodAsync(1);
  var result2 = SomeMethodAsync(2);
  var result3 = SomeMethodAsync(3);

  await Task.WhenAll(result1, result2, result3);

  ViewBag.Result1 = result1;
  ViewBag.Result2 = result2;
  ViewBag.Result3 = result3;

  return View()

}


public async Task<int> SomeMethodAsync(int i)
{
  //do some logic

  //make db call
  return await Task.Run( () => DbCall(i));
 }


 public int DbCall(i)
 {
   //make db call

   return valueFromDb;
 }

Поскольку я не использую Entityframework 6, я не могу сделать DbCall() асинхронным. я читал, что это не очень хорошая идея использовать Task.Run в проектах ASP.NET, поскольку Task.Run будет заимствовать поток из пула потоков ASP.Net и, следовательно, может вызвать проблемы с очередями при большом количестве запросов (поскольку будет меньше доступных потоков для обработки входящих запросов ).

1) Как я могу сделать свой метод асинхронным без использования Task.Run?

2) Лучше ли сделать метод синхронным, чем использовать Task.Run?


person Kaladin    schedule 12.12.2014    source источник
comment
Чем занимается ваш DbCall? Почти все провайдеры ado.net предоставляют асинхронные операции. Вы можете использовать это.   -  person Sriram Sakthivel    schedule 12.12.2014
comment
Он вызывает поиск по идентификатору (db.Departments.Find(id)). К сожалению, я использую Entityframework 4.3, который не поддерживает асинхронные вызовы. Только EF6 обеспечивает асинхронные вызовы, но в данный момент я не могу перейти на EF6.   -  person Kaladin    schedule 12.12.2014
comment
Если ваша логика в SomeMethodAsync() не содержит ничего, связанного с вводом-выводом, может быть лучше и проще использовать синхронный код.   -  person Vertigo    schedule 12.12.2014


Ответы (1)


2) Лучше ли сделать метод синхронным, чем использовать Task.Run?

Да.

В этом случае, поскольку у вас нет естественно-асинхронных API, доступных из EF6, следующим лучшим решением будет просто синхронизация.

Обратите внимание, что даже если у вас есть асинхронные API, один DbContext все равно может обрабатывать только одну операцию за раз. Вам придется создать несколько контекстов, чтобы выполнять несколько одновременных запросов, и это может стать сложным.

person Stephen Cleary    schedule 12.12.2014