Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 你在这里干什么?_C#_Async Await - Fatal编程技术网

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();