For microservice functions that simply call an external service or write to a data store, is there any point to using async/await in C#?
We're writing a fair number of these in AWS Lambdas, and it's hard to determine what the actual gain of async/await is in this context or where exactly it would be useful. For more traditional IIS web services, the asynchrony frees up threads in the OS and allows the server to service more requests.
But for AWS Lambdas, the functions only handle a single request per execution (limited to 1000 simultaneous executions). So if we have a long-running external process or external dependency with significant latency, each function execution will be hung up until the external process completes (assuming the Lambda is invoked synchronously).
Here's a sample Lambda with three handlers, the third of which I put into a separate Lambda called "DavidSleep" which simply represents a long-running external dependency. When I invoke a different Lambda called "DavidTest" using either of the first two handlers, I see no functional or performance difference between the async/await version and the one lacking async/await. Both functions require multiple concurrent Lambda executions and take the same amount of time.
So the async version appears to have no difference to the async-less version, but is there any?
public class Test
{
private IAmazonLambda lambda;
public Test()
{
lambda = new AmazonLambdaClient();
}
[LambdaSerializer(typeof(JsonSerializer))]
public async Task HandleAsync(Request request)
{
Console.WriteLine($"Executing for { request.Name }");
await lambda.InvokeAsync(new InvokeRequest
{
FunctionName = "DavidSleep",
InvocationType = InvocationType.RequestResponse,
Payload = JsonConvert.SerializeObject(request)
});
}
[LambdaSerializer(typeof(JsonSerializer))]
public void Handle(Request request)
{
Console.WriteLine($"Executing for { request.Name }");
lambda.InvokeAsync(new InvokeRequest
{
FunctionName = "DavidSleep",
InvocationType = InvocationType.RequestResponse,
Payload = JsonConvert.SerializeObject(request)
}).Wait();
}
[LambdaSerializer(typeof(JsonSerializer))]
public void Sleep(Request request)
{
Console.WriteLine($"{ request.Name }{ request.RequestId } begin");
Thread.Sleep(request.WaitInSeconds * 1000);
Console.WriteLine($"{ request.Name }{ request.RequestId } end");
}
}