Search code examples
azure-functionsazure-function-async

how to wait for an async call in azure function


I am trying to call face api async method from an Azure function. I am awaiting on an async method but Azure function goes off and completes it. How can I wait for the async operation to complete in Azure fucntion?

Here's my code (I am using VS 2017, .Net standard 2.0):

public static class IdentifyHttp
{
    [FunctionName("IdentifyHttp")]
    public static IActionResult Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequest req, TraceWriter log)
    {
        log.Info("C# HTTP trigger function processed a request.");


        string url = new StreamReader(req.Body).ReadToEnd();            

        //string url = req.Query["url"];

        Stream rtn = null;
        HttpWebRequest aRequest = (HttpWebRequest)WebRequest.Create(url);
        HttpWebResponse aResponse = (HttpWebResponse)aRequest.GetResponse();

        StreamReader sReader = new StreamReader(aResponse.GetResponseStream(), System.Text.Encoding.Default);

            rtn = sReader.BaseStream;           

        AnalyzeImageFaceAPIAsync(rtn);

        return url != null
            ? (ActionResult)new OkObjectResult($"Hello, {url}")
            : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
    }

    private static async void AnalyzeImageFaceAPIAsync(Stream s)
    {

        string PersonGroupId = "employees";
        FaceServiceClient FaceServiceAPIClient = new FaceServiceClient("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "https://eastus.api.cognitive.microsoft.com/face/v1.0");
        string name = "No one identified";

        //s.Seek(0, SeekOrigin.Begin);
        var faces = await FaceServiceAPIClient.DetectAsync(s);
        var faceIds = faces.Select(face => face.FaceId).ToArray();

        var results = await FaceServiceAPIClient.IdentifyAsync(PersonGroupId, faceIds);
        foreach (var identifyResult in results)
        {
            if (identifyResult.Candidates.Length > 0)
            {
                var candidateId = identifyResult.Candidates[0].PersonId;
                var person = await FaceServiceAPIClient.GetPersonAsync(PersonGroupId, candidateId);
                name = person.Name;


            }
        }
    }
}

Solution

  • You should declare the function with async Task AnalyzeImageFaceAPIAsync instead of async void AnalyzeImageFaceAPIAsync. In case of any errors in AnalyzeImageFaceAPIAsync they are not populated to your main function and you have to await your own function with: await AnalyzeImageFaceAPIAsync(rtn);