Search code examples
c#asp.netasynchronousasync-awaitaudio-fingerprinting

Correct Way to use an async Library with ASP.NET/MVC/REST


I have an async Library for audio file processing. Furthermore I want to offer these Methods via Rest. So I made an MVC WebApi Project. The library needs some time to start, so I added a class that offers a way to init and exposes the libraries main object.

public static class MusicHandler
{
    public static MusicCapture.MusicCapture MusicCapture;
    public static void init()
    {
        MusicCapture = new MusicCapture.MusicCapture("D:\\Temp", "D:\\test", "E:\\FingerPrintDB2.ss");
        MusicCapture.Start();
    }
}

I start it in Application_Start()

protected void Application_Start()
{
    MusicHandler.init();
}

Now when my init method contains some async calls like this:

var hashedFingerprints = command.Hash().Result;

The programm will just skip over these lines. They do not get executed for all I can tell. Same thing happens when I call any of the objects async methods from my REST endpoints. When I run the library not from ASP.NET/MVC the code works flawlessly.

I found some comments that said that this is a problem because of deadlocks, but no advice or code how to avoid this/make this work.

Thank you in advance.


Solution

  • I figured my Problem out, it was twofold.

    1. My library failing on start was a bug in the library that led to an exception which wasn't bubble up. I was able to mitigate this bug. Async calls on startup with a MVC App with .Result inside seem to actually be no problem.

    2. My REST calls failing on async could be fixed by changing the rest controllers methods to async. I never would have thought thats possible but I found an example here: https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html

    // GET api/music
    public async System.Threading.Tasks.Task<string> GetAsync()
    {
        string result = await MusicHandler.MusicCapture.DetectAsync(5);
        Console.WriteLine("Server returning: " + result);
        return result;
    }