在异步函数内调用非异步方法

时间:2020-09-08 06:37:34

标签: c# async-await

请帮助我了解以下代码的异步/等待操作。

1. public async Task OuterMethodAsync(MyObject obj1)

2. {

3.     var dbResult = await repo.SomeDB_GetCallAsync(obj1.id);

4.     var httpResult = await Function1ContainingHTTPCallAsync(dbResult);

5.     dbResult.param1 = obj1.param1;

6.     var isSuccess = Function2(httpResult, dbResult);

7.     await repo.SomeDB_UpdateAsync(dbResult);

8.     if(isSuccess)
9.      {
10.         // Do some stuff
11.     }

12. }

如果 Function2 的输入参数 httpResult 为空,则应返回false。

基于 Function1ContainingHTTPCallAsync

中的日志,
  1. 它已成功执行了http调用,
  2. 返回有效响应 httpResult ,它是一个非空字符串

但是,基于 Function2

中的日志,
  1. 它已收到输入参数 httpResult 为空
  2. 返回了错误的

在这里

  1. Function2 不异步
  2. Function1ContainingHTTPCallAsync 异步
  3. SomeDB_GetCallAsync 异步
  4. SomeDB_UpdateAsync 异步
  5. OuterMethodAsync 异步

我在这里看到的问题是isSuccess被设置为false。另外,请注意,有可能多次调用OuterMethod(这是HTTP调用失败的框架中的重试机制)。考虑到OuterMethod本身就是被称为HTTP调用的API,是否会导致此问题?

1 个答案:

答案 0 :(得分:2)

我在这里看到的问题是isSuccess设置为false,仅当第6行在第4行之前执行时才会发生。

您使用了正确的await,因此:第6行未执行,应先执行。您将不得不研究Function2可以返回false的情况,并且也许使用调试器来查看正在发生的情况。从这里我们可以看出,所示代码很好。

请注意,在调试环境中,可能有意义地定义/分配了isSuccess 的值 -例如,如果在OuterMethod。这并不意味着第6行已经执行。这只是意味着调试器会在幕后看到。严格来说,该值在第6行之前是未定义的,但实际上,由于C#编译器发出.locals init(至少当前是这样),因此它将是false,因为false是默认值bool

您可能还想检查OuterMethod是否可能被独立调用两次。