2014-01-02 5 views
7

У меня есть этот метод в моей службы:получить результат от метода асинхронной

public virtual async Task<User> FindByIdAsync(string userId) 
{ 
    this.ThrowIfDisposed(); 
    if (userId == null) 
    { 
     throw new ArgumentNullException("userId"); 
    } 
    return await this.repository.FindByIdAsync(userId); 
} 

, а затем в представлении у меня есть этот код:

using (var service = new UserService(new CompanyService(), User.Identity.GetUserId())) 
{ 
    var user = service.FindByIdAsync(id); 
} 

но пользователь является Task и не Пользователь. Я попробовал добавить для ожидания вызова, но я не могу использовать жду, если текущий метод не равен async. Как я могу получить доступ к классу ?

+5

Сделать текущий метод асинхронным и добавить ожидание. – Bas

+0

Можете ли вы показать код 'service.FindByIdAsync (id)'? – IamStalker

+1

«Асинхронные» методы подобны зомби: они распространяются. Асинхронные методы должны быть асинхронными. – Olivier

ответ

5

Лучшее решение сделать метод вызова async, а затем использовать await как Bas Брекелманс указал.

Когда вы делаете метод async, вы должны изменить тип возвращаемого (если это void, изменить его Task, в противном случае, изменить его от T к Task<T>) и добавьте Async суффикс к имени метода. Если тип возврата не может быть Task, потому что это обработчик событий, то вы можете использовать async void.

Если вызывающий метод является конструктором, вы можете использовать one of these techniques из моего блога. Это метод вызова - свойство getter, вы можете использовать one of these techniques из моего блога.

+1

Скажите помощнику ... Являетесь ли вы основным разработчиком инфраструктуры .net?Вы глубоко вовлечены в параллельное развитие в C# – IamStalker

+1

@IamStalker: Ха-ха, нет. Я не работаю для Microsoft. У меня есть много опыта в параллельных приложениях, поэтому я понимаю, откуда они идут, особенно с помощью 'async'. Существует сотрудник по имени Стивен * Toub *, который работает в Microsoft и глубоко связан с TPL, Dataflow и 'async'. –

+0

Stephen, проблема у меня в том, что мой вид виртуальный, поэтому он вызывает мою службу, но это не функция, поэтому я не могу добавить async :(есть ли какая-нибудь другая работа? – r3plica

7
  • Использование this в async методы без специальной резьбы автоподстройки объекта опасно
  • Если вы не можете использовать await, используйте код как следующее.

    Task<User> task = TaskFindByIdAsync(); 
    
    task.Wait(); //Blocks thread and waits until task is completed 
    
    User resultUser = task.Result; 
    
+0

Это действительно плохая практика. Это может быть скрытый тупик. [см. это] (http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html) – Olivier

+0

@Olivier Похоже, что это не так. Только нечеткий код в задаче [может вызвать тупик] (http://stackoverflow.com/questions/13140523/await-vs-task-wait-deadlock) –

+0

Хорошая привычка - никогда не полагаться на **, как ** методы при их вызове. Если Wait() находится в контекстном потоке, а метод Waited (не A-waited) использует «ожидание», тогда вы будете заторможены (потому что он ожидает, что основной поток будет доступен). – Olivier

Смежные вопросы