Возвратный список из метода async/wait

Я хочу сделать запрос asserver для webservice. Я называю это здесь:

List<Item> list = GetListAsync();

Вот объявление моей функции, которая должна вернуть список:

private async Task<List<Item>> GetListAsync(){
    List<Item> list = await Task.Run(() => manager.GetList());
    return list;
}

Если я хочу скомпилировать, я получаю следующую ошибку

Cannot implicitely convert type System.Threading.Tasks.Task<System.Collections.Generic.List<Item>> to System.Collections.Generic.List<Item>

Как я знаю. Если я использую модификатор async, результат автоматически завершается с помощью Task. Я думаю, что этого не происходит, потому что я использую Task.Run. Если я удалю часть Task.Run(() =>, я получу

Не удается выполнить выражение System.Collections.Generic.List

Я думаю, что я не полностью понял методы async/wait. Что я делаю неправильно?

Ответ 1

Вам нужно исправить свой код, чтобы дождаться загрузки списка:

List<Item> list = await GetListAsync();

Кроме того, убедитесь, что метод, в котором находится этот код, имеет модификатор async.

Причина, по которой вы получаете эту ошибку, заключается в том, что метод GetListAsync возвращает Task<T>, который не является завершенным результатом. Поскольку ваш список загружается асинхронно (из-за Task.Run()), вам нужно "извлечь" значение из задачи с помощью ключевого слова await.

Если вы удалите Task.Run(), список будет загружен синхронно, и вам не нужно будет использовать Task, async или await.

Еще одно предложение: вам не нужно ждать в методе GetListAsync, если единственное, что вы делаете, это просто делегировать операцию другому потоку, поэтому вы можете сократить свой код до следующего:

private Task<List<Item>> GetListAsync(){
    return Task.Run(() => manager.GetList());
}

Ответ 2

В дополнение к @takemyoxygen ответ на соглашение о том, что имя функции заканчивается на Async, заключается в том, что эта функция действительно асинхронна. То есть он не запускает новый поток и не просто вызывает Task.Run. Если это все код, который есть в вашей функции, лучше удалить его полностью и просто:

List<Item> list = await Task.Run(() => manager.GetList());

Ответ 3

Работает для меня:

List<Item> list = Task.Run(() => manager.GetList()).Result;

таким образом, нет необходимости отмечать метод асинхронным в вызове.