Home > Back-end >  Using return value from awaited method
Using return value from awaited method

Time:01-22

I'm trying to understand async methods and await, I've got this simple example:

using (var client = new AmazonSQSClient())
{
    var sqsRequest = new SendMessageRequest()
    {
        MessageBody = JsonConvert.SerializeObject(callProcessingRequest),
        QueueUrl = "https://sqs.eu-west-2.amazonaws.com/*****6014/W*****g"
    };

    LoggingHelper.Log(LoggingLevel.INFO, "Calling SQS", context);

    var sqsResponse = await client.SendMessageAsync(sqsRequest);

    LoggingHelper.Log(LoggingLevel.DEBUG,
        JsonConvert.SerializeObject(sqsResponse), context)
}

When I run this, the logging of sqsResponse never happens, however if I change

var sqsResponse = await client.SendMessageAsync(sqsRequest);

to

var sqsResponse = client.SendMessageAsync(sqsRequest).Result;

Then it works as expected.

With it being an async method I guess I should be using await with it, but not sure why it's not working.

EDIT: Whole method as requested. Adding .ConfigureAwait(false) didn't help.

public static async Task ProcessOutstandingDialplanItems()
{
    var context = new Context() { CurrentHandler = "PBXCallbacksLambdaFunction" };

    var callProcessingRequest = new CallProcessingRequest()
    {
        context = context,
        MethodToInvoke = "ProcessOutstandingDialPlanItems"
    };

    try
    {
        using (var client = new AmazonSQSClient())
        {
            var sqsRequest = new SendMessageRequest()
            {
                MessageBody = JsonConvert.SerializeObject(callProcessingRequest),
                QueueUrl = "https://sqs.eu-west-2.amazonaws.com/XXX6014/WXXXg"
            };

            LambdaLogger.Log("Calling SQS");

            var sqsResponse = await client.SendMessageAsync(sqsRequest)
                .ConfigureAwait(false);
            //var sqsResponse = client.SendMessageAsync(sqsRequest).Result;

            LambdaLogger.Log(JsonConvert.SerializeObject(sqsResponse));
        }
    }
    catch (Exception x)
    {
        LambdaLogger.Log(x.Message);
    }   
}

CodePudding user response:

My guess would be that you are already using Result or Wait (or something which is calling your code) in one of the method before in application which has SynchronizationContext (classic ASP.NET, UI apps like WPF, WinForms, etc.). That is a "good" way to end up in deadlock. One thing you can try - adding ConfigureAwait(false) to the call:

var sqsResponse = await client.SendMessageAsync(sqsRequest).ConfigureAwait(false);

But much better course of action - Don't Block on Async Code.

CodePudding user response:

From AWS Logging .NET:

AWS Lambda

These packages batch logging messages in a queue and send messages to CloudWatch Logs using a background thread. The use of the background thread means that the messages are not guaranteed to be delivered when used in AWS Lambda. The reason is because the background thread will be frozen once a Lambda event is processed and may not ever be unfrozen if more Lambda events are not received for some time.

When using Lambda it is recommended to use either the ILambdaContext.Logger.LogLine or the Amazon.Lambda.Logging.AspNetCore package.

  • Related