Я не могу найти правильный способ сделать это:

public Task<List<HWElDocument>> GetHWElDocumentsAsync(int? ProjectID = null)
{
    // Get all Items
    if (ProjectID == null)
        return database.Table<HWElDocument>().ToListAsync();

    // Or all items meeting a condition
    else
    {
        // This line has to be awaited, I think ?!?
        List<HWDocuProj> projList = await database.Table<HWDocuProj>().Where( item => item.ProjID == ProjectID).ToListAsync();
        // So that I can use the result here:
        return database.Table<HWElDocument>().Where(item => projList.Exists(p => p.ProjID == item.ID)).ToListAsync();
    }
}

Из-за ключевого слова await компилятор просит преобразовать функцию в асинхронную функцию. Но я делаю это, поэтому он отказывается, что результатом является Task<T'> ... Если я изменю тип возвращаемого значения на async List<HWElDocument'>, то эта строка выдает ошибку:

return database.Table<HWElDocument>().ToListAsync();

Как правильно этого добиться?

0
Belight 18 Сен 2021 в 00:56

2 ответа

Лучший ответ

Если я изменю тип возврата на async List<HWElDocument'>

Вам потребуются оба модификатора async для метода и возвращаемого типа Task. Итак, эта подпись должна работать:

public async Task<List<HWElDocument>> GetHWElDocumentsAsync(int? ProjectID = null)

async сообщает компилятору о необходимости внутреннего использования асинхронного конечного автомата и позволяет вам использовать ключевое слово await внутри метода.

А когда вы хотите вернуть что-то из асинхронного метода, вам понадобится тип возвращаемого значения Task<T>. При использовании async компилятор также обеспечит автоматическое включение вашего возвращаемого значения в задачу, чтобы вы могли просто вернуть значение напрямую.

Таким образом, ваша строка возврата должна также использовать await для ожидания задачи от ToListAsync, и тогда результат будет автоматически заключен в задачу результата вашего метода:

public Task<List<HWElDocument>> GetHWElDocumentsAsync(int? ProjectID = null)
{
    // Get all Items
    if (ProjectID == null)
        return await database.Table<HWElDocument>().ToListAsync();

    // Or all items meeting a condition
    else
    {
        List<HWDocuProj> projList = await database.Table<HWDocuProj>()
            .Where( item => item.ProjID == ProjectID)
            .ToListAsync();
        return await database.Table<HWElDocument>()
            .Where(item => projList.Exists(p => p.ProjID == item.ID))
            .ToListAsync();
    }
}
2
poke 17 Сен 2021 в 22:05

Вам нужно «ждать» асинхронной функции всякий раз, когда вы ее вызываете. Вы можете сделать это, просто поставив в начале ключевое слово "await":

return await database.Table<HWElDocument>().Where(item => projList.Exists(p => p.ProjID == item.ID)).ToListAsync();

А также

return await database.Table<HWElDocument>().ToListAsync();

Вам также понадобится "async" в сигнатуре вашего метода:

public async Task<List<HWElDocument>> GetHWElDocumentsAsync(int? ProjectID = null)

У Microsoft есть более подробное руководство по асинхронному программированию на C #: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/

2
ChickenOverlord 17 Сен 2021 в 21:58