0

I am implementing facial recognition functionality. I can upload a person and an image but when I try to send image for comparison the DetectAsync method fails with no error message. I am not sure if the problem lies in the method (I have successfully implemented it in other projects) or in the way I am sending the webcam/image through javascript or something else.

I am using javascript to detect a face on webcam and take a picture. The picture is sent to converted to a stream and send to DetectAsync(stream). It's in a try-catch block but I don't get an exception, it just returns to the UI where it seems frozen and I can't reload the page or navigate to another page. In the Quickwatch window, it I type faceServiceClient.DetectAsync(stream) and then force execution I get the following:

  • Exception: null
  • Id: 643
  • Status: WaitingForActivation
  • results: null (not yet computed)

a few others but these seemed like the most relevent

I expect to get either an array of FaceIDs (GUIDS). One per face in the image. Or an error message. After I get GUIDS I can try to find a match against faces in my personGroup. If I find a match I return the username to my UI. I have gotten this to work in an MVC app. This is an ASP.NET app.

code:

public async Task<string> DoFacialRecognition(string image)
{
    string response = "";
    FaceServiceClient faceServiceClient = new FaceServiceClient(subscriptionKey);
    try
    {  
        var imageToSend = ConvertBase64ToImage(image.Substring(22));

        Stream stream = ConvertToStream(imageToSend, ImageFormat.Png);

        var faces = await faceServiceClient.DetectAsync(stream, true, false);
        var faceIds = faces.Select(face => face.FaceId).ToArray();
    }
....
}
darthnoob
  • 19
  • 5

1 Answers1

0

The issue was with the thread or threads... Im not sure of the technicality or terms but I will explain as best I can. This was an aspx page making an ajax call to an async method. This was the behavior I was expecting:
aspx-> ajax-> async method A-> async method B-> back to A-> back to ajax-> ajax deals with response.

what was actually happening:
aspx-> ajax-> async method A-> async method B-> back to ajax or aspx.

But ajax is waiting for a response from method A so it is ignoring response from method B (probably not even in the right format anyway). The page is still 'active' but when user tries to do anything the server doesn't respond because method A is still waiting for a response from B and is locking the code.

If you know more about threads and async calls feel free to correct my understanding!

to resolve: The info I needed to resolve was provided by Stephen Cleary in this post: How to call asynchronous method from synchronous method in C#?.

you need to 'hide' the async method from the ajax call. To do this Stephen has a nuget packages called Nito.AsyncEx.

the sequence then looks like:
aspx-> ajax-> method A-> async method B-> back to A-> back to ajax-> ajax deals with response.
Note that method A is no longer async.

and code looks like this:

using Nito.AsyncEx;
[WebMethod]
    public static string CheckImage(string image)
    {
        var result =  AsyncContext.Run(() => MyAsyncMethod(image));           
        return result; 
    }

    private static async Task<string> MyAsyncMethod(string image)
    {
        //do async stuff
    }
darthnoob
  • 19
  • 5