c# - 通过 await 关键字返回任务和不使用 await 关键字返回的主要区别是什么?

标签 c# asp.net multithreading task-parallel-library

我正在包装 AspNet.Identity。但有些事情让我对 TPL 感到困惑。

第一个例子:

    public virtual async Task<IdentityResult> RemovePasswordAsync(string userId)
    {
        var user = _store.FindByIdAsync(userId).Result;
        if (user == null)
            throw new InstanceNotFoundException("user");

        user.PasswordHash = String.Empty;
        user.SecurityStamp = String.Empty;
        return await UpdateAsync(user);
    }

    public virtual async Task<IdentityResult> UpdateAsync(TUser user)
    {
        await _store.UpdateAsync(user);
        return new IdentityResult();
    }

第二个例子:

    public virtual Task<IdentityResult> RemovePasswordAsync(string userId)
    {
        var user = _store.FindByIdAsync(userId).Result;
        if (user == null)
            throw new InstanceNotFoundException("user");

        user.PasswordHash = String.Empty;
        user.SecurityStamp = String.Empty;
        return UpdateAsync(user);
    }

    public virtual async Task<IdentityResult> UpdateAsync(TUser user)
    {
        await _store.UpdateAsync(user);
        return new IdentityResult();
    }

客户会这样调用它:

    result = await _userManager.RemovePasswordAsync(user.Id);

我的第一个问题是:

当客户端调用第二个方法时,工作从 IO 线程卸载到线程池线程。当调用 RemovePasswordAsync 时,它会调用具有 await 关键字的 UpdateAsync。那么,此时此线程池线程是否卸载到另一个线程池线程?还是 TPL 继续使用相同的线程?

我的第二个问题是;构造这个async方法的第一个实现和第二个实现的主要区别是什么?

编辑:

这是 UserStore 类的更新方法。 (_store.UpdateAsync(用户))

    public Task UpdateAsync(TUser user)
    {
        if (user == null)
            throw new ArgumentNullException("user");

        return _userService.UpdateAsync(user);
    }

这是UserService类的更新方法

    public Task UpdateAsync(TUser user)
    {
        return Task.Factory.StartNew(() => Update(user));
    }

最佳答案

我会回答你的第一个问题。

您误解了 async/await 的工作原理。

async 方法将同步运行至少,直到它遇到第一个await 语句。 当它遇到 await 时,它有两个选项:

  • 如果可等待(例如 Task)已经完成,则继续执行当前上下文(即 UI 线程或 ASP.NET 请求的上下文)。
  • 如果 awaitable 尚未完成,它会包装方法主体的其余部分并安排在任务完成时在当前上下文(即 UI 线程)(*) 上执行。

根据这个定义,您的整个代码将在同一个 ASP.NET 请求的上下文中运行。

然而,

_store.UpdateAsync 可能会产生一个 ThreadPool 线程(例如,通过使用 Task.Run)。

已更新

根据您更新的答案,Update(user) 将在 ThreadPool 线程上运行。其他一切都将在当前上下文中运行。


(*) 如果没有同步上下文(即控制台应用程序),方法主体的其余部分将安排在 ThreadPool 线程上运行

关于c# - 通过 await 关键字返回任务和不使用 await 关键字返回的主要区别是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22015164/

相关文章:

c# - 如何使用 ?枚举中的字符

c# - 如何在我的应用程序中集成实时 Skype 状态?

c# - 使用线程进行数据库操作的最佳方式是什么?

c# - 静态属性如何在 asp.net 环境中工作?

C# 如何在命令行应用程序中使用异步方法运行线程

c# - 如何实现线程安全的随机数

c# - 无法从 Derived<Derived 2T> 转换为 BaseT<base 2T>

C# 导入 .CSV 数据到 MySQL 表只复制 1 列

asp.net - 错误 404 的默认重定向

c# - 匿名类型出现在两个错误