C# 你在这里干什么?
给定方法签名:C# 你在这里干什么?,c#,async-await,C#,Async Await,给定方法签名: (awaitable) Task<Token> ITokenService.GetAPIToken(); 我的理解是:GetAPIToken被调用,当前方法(GetUser)返回一个Task对象(稍后将提供一个User对象)。当前方法的执行仅在GetAPIToken方法返回后继续 如果我错了,当代码等待GetAPIToken()方法返回时,token的类型/值是什么 我知道调用此方法的结果会有所不同,因为可以使用或不使用wait关键字调用它。对于post,请假设正在
(awaitable) Task<Token> ITokenService.GetAPIToken();
我的理解是:GetAPIToken
被调用,当前方法(GetUser
)返回一个Task
对象(稍后将提供一个User
对象)。当前方法的执行仅在GetAPIToken
方法返回后继续
如果我错了,当代码等待GetAPIToken()
方法返回时,token
的类型/值是什么
我知道调用此方法的结果会有所不同,因为可以使用或不使用
wait
关键字调用它。对于post,请假设正在使用await
在await
行上调用它,实际上GetUser()
的执行已停止(等待),直到GetAPIToken()
返回。这是正确的。因此,token
在从GetAPIToken()
返回中获取它之前没有任何值(在本例中甚至声明)
GetUser()
返回的内容取决于调用它的方式,有无wait
操作符。如果使用wait
调用,则GetUser()
的调用方也将等待它完成。同样,在这种情况下,调用方最终将获得由GetUser()
返回的User
,而不是任务
在这种情况下,并行运行任何东西都不会使您受益
另一方面,如果在调用GetUser()
时没有使用wait
操作符,则会发生两种不同的情况:GetUser()
在调用方实际到达您的线路时,会提前返回调用方;它直接返回一个任务
,而不是用户
——毕竟还没有创建任何任务
通过这个任务
调用方可以稍后(在并行完成其他事情之后,这就是重点)获得结果用户
。这可以通过不同的方式实现——最惯用的方式是等待它;或者查看任务的方法和属性
理解事物何时并行运行是很重要的。在这种情况下(如果调用GetUser()
时未调用wait
),则有可能GetUser()
返回,而您继续执行操作,而在另一个线程中,getapitonk()
尚未返回,因此token
未初始化
用图表查看这篇漂亮的MSDN文章:
在带有await
的行上,确实停止执行GetUser()
,直到getapitonk()
返回。这是正确的。因此,token
在从GetAPIToken()
返回中获取它之前没有任何值(在本例中甚至声明)
GetUser()
返回的内容取决于调用它的方式,有无wait
操作符。如果使用wait
调用,则GetUser()
的调用方也将等待它完成。同样,在这种情况下,调用方最终将获得由GetUser()
返回的User
,而不是任务
在这种情况下,并行运行任何东西都不会使您受益
另一方面,如果在调用GetUser()
时没有使用wait
操作符,则会发生两种不同的情况:GetUser()
在调用方实际到达您的线路时,会提前返回调用方;它直接返回一个任务
,而不是用户
——毕竟还没有创建任何任务
通过这个任务
调用方可以稍后(在并行完成其他事情之后,这就是重点)获得结果用户
。这可以通过不同的方式实现——最惯用的方式是等待它;或者查看任务的方法和属性
理解事物何时并行运行是很重要的。在这种情况下(如果调用GetUser()
时未调用wait
),则有可能GetUser()
返回,而您继续执行操作,而在另一个线程中,getapitonk()
尚未返回,因此token
未初始化
用图表查看这篇漂亮的MSDN文章:
我的理解是:GetAPIToken
被调用,当前方法(GetUser
)返回一个Task
对象(稍后将提供一个User对象)。当前方法的执行仅在GetAPIToken
方法返回后继续
非常接近。让我们用两种方法把它变脆
首先,让我们区分返回(这意味着将控制权返回给调用者)和完成(这意味着方法表示的任务已完成,并且我们有它的值,或者,在异常完成的情况下,有一个异常)
在非异步方法中,我们不需要进行区分,因为只有在完成时才将控制权返回给调用方。在异步方法中,我们可以将调用方作为挂起返回(因为等待未完成的任务)或作为完成返回(当表示的任务被指示为完成时)
第二,它有助于根据任务创建时完成的情况来表达工作流;例如,在缓存的情况下可能会发生这种情况
因此,现在让我们重新陈述您的理解:
- 调用
GetAPIToken
,并将任务返回给当前用户
- 如果任务已完成,则GetApiToken在完成所有工作时返回。GetUser从已完成的任务中提取令牌,并在不挂起的情况下继续
- 如果任务未完成,并且这是GetUser中的第一个等待,则GetUser将创建一个
任务
GetUser
将GetUser
的剩余部分指定为继续部分
public async Task<User> GetUser(string userId)
{
Token token = await TokenService.GetAPIToken();
//..........
}
Token x = Foo();