在多个方法调用上使用asyc/await/task

Bv2*_*202 0 c# asynchronous async-await

我一直在尝试理解async/await以确保在从数据库加载内容时UI不会阻塞.这是我到目前为止所做的,但它根本不起作用:

VM:

public LoadingViewModel(IRoleService roleService)
{
    RoleService = roleService;
    StartLoading();
}

private IEnumerable<Role> StartLoading()
{
    Roles = RoleService.GetAllRoles();
}
Run Code Online (Sandbox Code Playgroud)

RoleService:

public IEnumerable<Role> GetAllRoles()
{
    return Repository.GetAll<Role>().Result;
}
Run Code Online (Sandbox Code Playgroud)

库:

public async Task<IQueryable<T>> GetAll<T>() where T : class
{
    return await Task.Run(() => Context.Set<T>());
}
Run Code Online (Sandbox Code Playgroud)

我认为这可行,但显然它不会因为UI仍然挂起.我确实通过在RoleService中创建另一个任务来实现它,但我不认为你应该做更多的任务......

我已经尝试了一段时间,我已经阅读了很多关于它的内容,但我只是不明白.

有人可以解释为什么这不起作用,我怎么能真正让它工作?

编辑:看了答案后,我现在有了这个,但它仍然无效.我稍后会看一下构造函数问题.

VM:

public LoadingViewModel(IRoleService roleService)
{
    RoleService = roleService;

    //change this later
    var roles = StartLoading();
}

private async Task<IEnumerable<Role>> StartLoading()
{
    var roles = await RoleService.GetAllRolesAsync();

    foreach (var role in roles)
    {
        Console.WriteLine(role.Name);
    }
    return roles;
}
Run Code Online (Sandbox Code Playgroud)

RoleService:

public async Task<IEnumerable<Role>> GetAllRolesAsync()
{
    return await Repository.GetAll<Role>();
}
Run Code Online (Sandbox Code Playgroud)

库:

    public async Task<IQueryable<T>> GetAll<T>() where T : class
    {
        return await Task.Run(() => Context.Set<T>());
    }
Run Code Online (Sandbox Code Playgroud)

用户界面仍然悬而未决 - 我现在做错了什么?

Ser*_*rvy 7

您正在调用Result该任务,该任务同步等待任务完成.由于您是从UI线程调用它,因此它将在Task执行期间阻止UI线程.由于该任务需要将回调发布到UI线程,并且您正在阻止UI线程并阻止处理任何UI消息,这Task当然永远不会完成,从而导致UI永远挂起.

您需要不同步等待异步操作; 你需要整个调用堆栈是异步的.(你需要"一直异步".)