1

I have async methods inside my libraries and the top level call is made at the handler of AWS Lambda functions synchronously (for some reason not to discuss here). I wonder if any calls made down the track be asynchronous by any chance? or because the first caller does it synchronously will everything be synchronous?

public void LambdaHandler(Input inp, ILambdaContext context)
{
    method1().GetAwaiter().GetResult();
}

private async Task method1()
{
    await method2();
    await method3();
}

private async Task method2()
{
    //do something
}

private async Task method3()
{
    //do something
}
Johnny
  • 8,939
  • 2
  • 28
  • 33
Rez.Net
  • 1,354
  • 2
  • 19
  • 28

2 Answers2

3

method2 and method3 will do whatever they always have done. If they are purely synchronous behind a Task API, then they will continue to be synchronous; if they are asynchronous, then they will continue to be asynchronous. The only question here is: what will LambdaHandler do, and the answer to that is simply:

  • it will block until they are complete

If they are already complete synchronously, then fine; if they aren't, then you've tied up a thread in a sync-over-async block. This could by itself cause a deadlock if your code uses a sync-context or task-scheduler that only has a single worker (which isn't uncommon), as the thread that the async code will need to do any post-processing will be stuck waiting at GetResult(). So the async part can't complete, and GetResult() can't complete.

You should avoid sync-over-async like the plague. There is a reason it is considered an anti-pattern.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Re: sync-over-async as an antipattern: in this case it probably doesn't make a huge amount of difference in practice (aside from the deadlock concern which I assume doesn't apply in this context since the OP's code apparently works fine) since lambdas are charged per duration anyway, afaik there is no real implication of having the handler execute synchronously vs. asynchronously. – Ant P Jul 24 '19 at 10:54
1

The methods down below the call stack will run asynchronously.

But the entire thing would block and wait for the task to complete.

The better way is to modify LambdaHandler to return Task and use await instead of calling the GetAwaiter.

Help link

Artyom Ignatovich
  • 591
  • 1
  • 3
  • 13
  • I tried this and did not work: public async Task MyHandler(APIGatewayProxyRequest request, ILambdaContext context) We use (and hard to change everything back if this does not work) Lambda Proxy integration. – Rez.Net Jul 24 '19 at 07:14
  • Being able to see the extended example may reveal the causes of the problem. Based on the code example presented no assumptions could be made on further usage of this method. Sure there must be a way to integrate this using task-based pattern especially in web programming context. – Artyom Ignatovich Jul 24 '19 at 07:20
  • @Rez.Net can you elaborate on what "did not work" about it? – Ant P Jul 24 '19 at 07:48
  • We figured the issue out, there was a problem with the way we had set up some internal processes to do with lambda handlers. We have made our Lambda handlers all async now, thanks. – Rez.Net Jul 30 '19 at 04:35