我试图找到使用多个相关调用使我的API异步的最佳方法
<top routes...>
public async Task<IHttpActionResult> Post()
{
/*... some sync items*/
int userId= await _ef.saveUser();
var siteInfo = callsite(userId);
return await _ef.updateUserLastModified(); //need to wait for other 2
}
所以所有3都需要按顺序排列,我可以创建一个运行该任务的私有函数吗?使它异步有什么好处吗?我基本上只是想让它连接这3个电话。
答案 0 :(得分:3)
你有什么好!假设最后一行取决于前两行,您的代码是等待异步调用并执行同步代码的正确方法:
public async Task<IHttpActionResult> Post()
{
int userId = await _ef.saveUser(); // 1
var siteInfo = callsite(userId); // 2
return await _ef.updateUserLastModified(); // 3
}
第2行将在第1行完成后才会执行,然后等待第3行并返回。方法结束前的任何同步代码也将“正常”执行。
Async与多线程不是一回事 - 它只是告诉编译器在继续之前需要等待一些异步事情完成的方法。
答案 1 :(得分:1)
async
和await
的美妙之处在于,您可以编写代码,使其看起来像同步代码。让我们分解您所拥有的内容,因为它是异步编程的正确实现。
public async Task<IHttpActionResult> Post()
{
int userId = await _ef.saveUser();
var siteInfo = callsite(userId);
return await _ef.updateUserLastModified();
}
方法签名
我们定义了可公开访问的async
方法,可以快乐地返回Task<IHttpActionResult>
并命名为Post
,非常棒。
Body Line 1
然后我们声明并分配一个名为userId
的变量等待_ed.saveUser()
调用的结果。这意味着saveUser
必须返回Task<int>
,否则无法编译。由于我们在方法签名中使用了await
关键字,因此此方法块中可以使用async
关键字。当我们await
saveUser
调用时,内部异步状态机捕获返回位置,然后立即将控制权返回给调用线程 - 允许它在其他地方工作。在一段未知的时间之后,当用户的保存完成时,控制然后从中断处继续(可能在同一线程上或甚至在线程池线程上)并且分配userId
变量。 / p>
Body Line 2
一旦我们有了userId
,那么我们才会继续下一行。如果我们错误地省略了前一行中的await
并且错误地将我们的userId
变量声明为var
而不是int
,那么因为变量会有问题是Task<int>
而不是我们想要的具体化int
。请注意,这是同步代码 - 这是完全正常和可接受的,实际上是鼓励的。并非每一条逻辑都需要async
,并且短语&#34; async is as way&#34;实际意味着别的东西。这意味着,例如,Post
方法不是void
方法,而是.Result
上的saveUser
,而是一直异步。
Body Line 3
最后,我们将返回_ef.udateUserLastModified()
方法的等待结果。我们知道这也会返回Task<IHttpActionResult>
。