2

我遇到了一个小问题,我编写了一个 asp.net web api 服务,并在控制器上自动添加了“async”,当然这现在需要我使用 await。

我遇到的问题是我的控制器连接到服务层,然后该服务层连接到数据层-该数据层是调用 GET 的 ASYNC 版本以对另一个 REST 服务进行异步调用的层-所以这很简单,我可以将我的数据层方法转换为具有“async”关键字,然后我将等待 HttpClient GetSync 调用。

但是我的服务层支持 async / await 我需要将返回类型更改为 Task 但服务层实际上没有做任何 ASYNC 它对实际调用 HttpClient 异步方法的数据层的调用。

因此,考虑到我具有以下层结构,我有 2 个选项。

ASP.NET Web Api >> 服务层 >> 数据层

仅在数据层中使用 async 和 await 并完成它。

或者将 async 和 await 放在控制器和服务层的方法上,这需要重构,因为我需要返回 Task。

我想在我不完全理解的地方,从技术上讲,唯一的阻塞调用将在数据层中,所以要让所有线程返回线程池以供使用,我应该只关心在数据层上放置 async 和 await 吗?

我什么时候需要在控制器上使用模式???

期待任何帮助

4

2 回答 2

6

我在控制器上自动添加了“异步”,当然这现在需要我使用等待。

那是倒退。如果您async需要使用await.

仅在数据层中使用 async 和 await 并完成它。

您不应该在同步 API 中包装异步方法。在服务器代码中尤其如此,因为这样您就失去了async.

或者将 async 和 await 放在控制器和服务层的方法上,这需要重构,因为我需要返回 Task。

这是正确的做法。请遵循以下准则:

  1. 不要阻塞async代码。例如,不要调用Task.Waitor Task<T>.Result。我在我的博客上描述了这如何导致死锁,但即使你破解它以可靠地工作,你仍然会失去async服务器端的所有好处。
  2. 避免async void。特别是在服务器端。
  3. 代替Waitor Result,使用await. 这意味着等待方法必须是async Taskor async Task<T>,这意味着调用等待方法的方法也必须等待。因此,async将通过您的代码“成长”。这是正常和正确的。

您可能会发现我关于异步编程最佳实践的文章很有帮助。

于 2013-09-19T15:07:20.120 回答
1

如果您的调用线程没有任何意义可做,那么创建一个单独的任务来为您完成工作没有任何好处。

但是,如果调用线程有其他事情要做,例如保持 UI 响应,那么调用线程可能希望在单独的任务中调用您的函数,做其他事情,当它需要结果时等待结果。

例子:

private async YourAsyncWebFunction(...)
{
    // do some processing
    // call other async functions ans wait for it to finish:
    await OtherAsync(...);
    var result = await OtherAsync2(...)
    if (result == ...) { ... }
}

private void MyMainFunction(...)
{
    var taskWebFunction = Task.Run( () => YourAsyncWebFunction(...));
    // do other things
    // after a while: you need the task to finish:
    await taskWebFunction;
    // do other things
 }

如果您的主函数是事件处理程序,您不必执行 Task.Run,​​只需将事件处理程序声明为异步

事件处理程序是唯一可能返回 void 而不是 Task 或 Task <TResult>的异步函数

private async void OnButton1_Clicked(object sender, ...)
{
     // do some processing
     await YourAsyncWebFunction(...)
}
于 2015-08-10T10:34:42.950 回答