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

时间:2015-02-06 18:34:49

标签: c# asynchronous async-await

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

VM:

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

private IEnumerable<Role> StartLoading()
{
    Roles = RoleService.GetAllRoles();
}

RoleService:

public IEnumerable<Role> GetAllRoles()
{
    return Repository.GetAll<Role>().Result;
}

存储库:

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

我认为这可行,但显然它并没有因为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;
}

RoleService:

public async Task<IEnumerable<Role>> GetAllRolesAsync()
{
    return await Repository.GetAll<Role>();
}

存储库:

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

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

1 个答案:

答案 0 :(得分:7)

您在任务上调用Result,同步等待任务完成。由于您从UI线程调用此函数,因此它将在Task执行期间阻止UI线程。由于该任务需要向UI线程发送回调,并且您正在阻止UI线程并阻止处理任何UI消息,因此Task当然永远不会完成,从而导致UI永远悬空

您需要不同步等待异步操作;你需要整个调用堆栈是异步的。 (你需要&#34;异步上升&#34;。)