这是我的意思:
public Task<SomeObject> GetSomeObjectByTokenAsync(int id)
{
string token = repository.GetTokenById(id);
if (string.IsNullOrEmpty(token))
{
return Task.FromResult(new SomeObject()
{
IsAuthorized = false
});
}
else
{
return repository.GetSomeObjectByTokenAsync(token).ContinueWith(t =>
{
t.Result.IsAuthorized = true;
return t.Result;
});
}
}
上述方法可以被等待,我认为它与基于任务的异步模式所建议的方式非常相似?(我知道的其他模式是APM和EAP模式。)
现在,下面的代码怎么样:
public async Task<SomeObject> GetSomeObjectByToken(int id)
{
string token = repository.GetTokenById(id);
if (string.IsNullOrEmpty(token))
{
return new SomeObject()
{
IsAuthorized = false
};
}
else
{
SomeObject result = await repository.GetSomeObjectByTokenAsync(token);
result.IsAuthorized = true;
return result;
}
}
这里的主要区别在于方法是
async
并且使用await
关键字 - 那么与先前编写的方法相比,这会有什么变化?我知道它也可以-被等待。任何返回任务的方法都可以,除非我弄错了。我知道每当将方法标记为
async
时,使用那些switch语句创建状态机,并且我知道await
本身不使用线程-它根本不阻塞,线程只是去做其他事情,直到被调用回来继续执行上面的代码。但是,当我们使用
await
关键字调用这两种方法时,它们之间的根本区别是什么?是否有任何区别,如果有-哪个更好?编辑:我觉得第一个代码片段更好,因为我们有效地省略了async/await关键字,没有任何后果-我们返回一个将继续同步执行或者在热路径上已经完成的任务(可以缓存)。
result.IsAuthorized = true
将在线程池上运行,而在第二个例子中,它可能会在调用GetSomeObjectByToken
的同一线程上运行(如果它有安装了SynchronizationContext,例如它是一个UI线程)。如果GetSomeObjectByTokenAsync
抛出异常,行为也会稍有不同。通常情况下,相对于ContinueWith
,await
更容易阅读,因此更受欢迎。 - canton7