вызвать метод asyn c внутри Task.Run - PullRequest
0 голосов
/ 13 марта 2020

приведенный ниже код выполняется внутри asp. net mvc приложения

public async Task<string> GetCustomers1(){
    return await getcustomer1Async();
}
public async Task<string> GetCustomers2(){
    return await getcustomer2Async();
}
public async Task<JsonResult> Index(){
   var result1 =Task.Run(()=>GetCustomers1());
   var result2 =Task.Run(()=>GetCustomers2());
   Task.WaitAll(result1,result2);

}

Я уверен, что при запуске задачи будут созданы два потока для выполнения методов GetCustomers1, GetCustomers2. - мой вопрос: когда методы GetCustomers1 и GetCustomers2 достигают строки, в которой есть слово await, следует ли возвращать незавершенную задачу, а где возвращать незавершенную задачу? Возвращается ли поток в пул потоков? -Task.WaitAll будет ли основной поток занят до тех пор, пока другие задачи не будут завершены sh запущены?

Я знаю, что вы не должны использовать tak.run, если метод асинхронный. Но я хочу знать, как код работает внутри при таком сценарии.

Ответы [ 2 ]

2 голосов
/ 13 марта 2020

Ясно, что при выполнении задачи будут созданы два потока для выполнения методов GetCustomers1, GetCustomers2.

Task.Run не создает потоки. Он помещает очередь в пул потоков.

Мой вопрос: когда методы GetCustomers1 и GetCustomers2 достигают строки, содержащей слово await, должна быть возвращена неполная задача, где должна быть возвращена неполная задача? Возвращается ли поток в пул потоков?

Да, поток возвращается в пул потоков. Когда await готов возобновить выполнение, «продолжение» этого метода ставится в очередь в пул потоков. Обратите внимание, что продолжения могут выполняться или не выполняться в одном потоке; они могут работать в любом потоке пула потоков.

Task.WaitВсе ли у вас будет занят основной поток до тех пор, пока другие задачи не будут завершены sh?

Да, что это то, что Task.WaitAll сделает. Он также блокирует асинхронный код, что не очень хорошая идея. Лучше всего go asyn c полностью .

Я знаю, что вы не должны использовать tak.run, если метод асинхронный.

Использование Task.Run для асинхронного кода - это нормально. Но в общем случае вы не должны использовать Task.Run на ASP. NET, потому что это ставит в очередь работу в пул потоков, а не позволяет ASP. NET иметь полный контроль над пулом потоков. Вместо этого вызывайте асинхронный код напрямую и используйте асинхронный код (Task.WhenAll) вместо кода блокировки (Task.WaitAll):

public async Task<string> GetCustomers1() {
  return await getcustomer1Async();
}
public async Task<string> GetCustomers2(){
  return await getcustomer2Async();
}
public async Task<JsonResult> Index(){
  var result1 = GetCustomers1();
  var result2 = GetCustomers2();
  await Task.WhenAll(result1, result2);
}
0 голосов
/ 13 марта 2020

Да, в строке await методы GetCustomers1 и GetCustomers2 немедленно возвратят незавершенную задачу, предполагая, что задачи, возвращенные из getcustomer1Async() и getcustomers2Async(), являются незавершенными. Ключевое слово await позволяет писать код под строкой await, которая будет запускаться после завершения ожидаемой задачи. В вашем случае нет кода ниже строки await, так что вы также можете напрямую возвращать задачи, не ожидая их:

public Task<string> GetCustomers1()
{
    return getcustomer1Async();
}

Обратите внимание, что пропало не только ключевое слово await, но и async.

Что касается метода Index, он должен дать вам предупреждение во время компиляции за отсутствие await внутри метода, помеченного ключевым словом async. Вам, вероятно, следует изменить его на что-то вроде этого:

public async Task<JsonResult> Index()
{
   var task1 = Task.Run(() => GetCustomers1());
   var task2 = Task.Run(() => GetCustomers2());
   string[] results = await Task.WhenAll(task1, task2);
   //...use the results to create a JsonResult and return it
}

Наконец, имейте в виду, что обычной практикой является добавление суффикса Async к методам, которые возвращают Task. Таким образом, метод GetCustomers1 должен быть переименован в GetCustomers1Async, Index должен быть переименован в IndexAsync et c. Вы можете прочитать соответствующие рекомендации здесь .

...