Проверьте, является ли Task истинным или ложным (C #)

#c# #task-parallel-library

#c# #задача-параллельная-библиотека

Вопрос:

У меня был метод, чтобы проверить количество арендодателей шт LandlordTypes

У меня был этот код для проверки

 var type = _landlordTypeRepository.GetAll()
    .Include(x => x.Landlords)
    .FirstOrDefault(x => x.Id == input.Id);

if (type.Landlords.Count > 0)
{
    throw new UserFriendlyException(L("ThisTypeIsInUse"));
}
  

Но я переписал его следующим образом

 var type = _landlordTypeRepository
    .GetAll()
    .AnyAsync(x=> x.Id == input.Id amp;amp; x.Landlords.Any());
  

Но теперь возвращайте идентификатор типа Task<bool>

Как я могу использовать это в if?

Комментарии:

1. Вы должны ожидать его или получить от него результат

2. Вы должны await выполнить свой запрос таким образом, чтобы он Task<bool> был развернут в bool . Однако второй запрос теперь отличается от первого. Первый запрос вернул тип арендодателя, второй запрос возвращает, true если идентификатор типа существует и тип содержит арендодателей.

Ответ №1:

Вам нужно использовать await :

 var type = await _landlordTypeRepository.GetAll().AnyAsync(x=> x.Id == input.Id amp;amp; x.Landlords.Any());
  

Ваш метод также должен быть помечен как async .

Я рекомендую вам ознакомиться с async — await.

Ответ №2:

Используйте await для «разворачивания» Task результата

 bool type = await _landlordTypeRepository.GetAll().AnyAsync(x=> x.Id == input.Id amp;amp; x.Landlords.Any());
  

Также отметьте вызывающий метод как async

 async Task SomeMethod() {
    //..

    bool type = await _landlordTypeRepository.GetAll().AnyAsync(x=> x.Id == input.Id amp;amp; x.Landlords.Any());

    //..
}
  

Ответ №3:

Вы можете либо использовать await ключевое слово, либо просто поместить .Result в конец задачи, чтобы получить искомое значение.

При использовании await сигнатура вашего метода должна быть асинхронной и также должна возвращать Task (например, Task<string> или просто Task для void), если это не событие, которое затем может быть async void .

Использование .Result заблокирует текущий поток, что означает, что также может заморозить пользовательский интерфейс!

Комментарии:

1. Использование .Result не подходит для асинхронных методов. Вы блокируете текущий поток, и тогда может произойти много плохих вещей.

2. @Nick Я согласен! Но иногда другого выбора нет. Возможно, я ошибаюсь, но, например, в конструкторах я должен использовать . Результат вместо ожидания / асинхронности. Кроме того, внутри Parallel я использую. Результат поэтому я намеренно блокирую поток, иначе, если я использую async, он перейдет к строке после Parallel.

3. Я бы никогда не использовал асинхронный метод в конструкторе. Конструкторы должны выполняться быстро и быть независимыми от контекстов. Лучше используйте заводской метод и сделайте его асинхронным.

Ответ №4:

Задача — это ссылочная структура данных, используемая для асинхронных вызовов. Оно содержит свойство .Result, которое будет заполнено возвращаемым значением после завершения вызова. Поскольку это асинхронный вызов, вы не можете быть уверены, что вызов был завершен при получении задачи, как вы сделали здесь.

Существует два основных способа решения этой проблемы:

  1. Если вы находитесь внутри асинхронного контекста (метод, использующий ключевое слово async), вы могли бы просто использовать await -ключевое слово для ожидания и развертывания результата. var type = await _landlordRepository.GetAll().AnyAsync(...);

  2. Если вы находитесь в синхронном контексте, вы можете использовать Task .Wait() для ожидания вызова, а затем считывания результирующего значения из Task<T>.Result .

    var task = _landlordRepository.GetAll().AnyAsync(...).Wait();
    var type = task.Result

Как указывали люди, использование .Result обычно не рекомендуется, поскольку это блокирующий вызов.