Search code examples
async-awaitblazorblazor-client-sideblazor-webassembly

Blazor Startup Error: System.Threading.SynchronizationLockException: Cannot wait on monitors on this runtime


I am trying to call an api during the blazor(client side) startup to load language translations into the ILocalizer.

At the point I try and get the .Result from the get request blazor throws the error in the title.

This can replicated by calling this method in the program.cs

  private static void CalApi()
    {
        try
        {
            HttpClient httpClient = new HttpClient();
            httpClient.BaseAddress = new Uri(@"https://dummy.restapiexample.com/api/v1/employees");
            string path = "ididcontent.json";
            string response = httpClient.GetStringAsync(path)?.Result;
            Console.WriteLine(response);
        }
        catch(Exception ex)
        {
            Console.WriteLine("Error getting api response: " + ex);
        }

    }

Solution

  • Avoid .Result, it can easily deadlock. You get this error because the mechanism is not (cannot be) supported on single-threaded webassembly. I would consider it a feature. If it could wait on a Monitor it would freeze.

    private static async Task CalApi()
    {
       ... 
       string response = await httpClient.GetStringAsync(path); 
       ...
    }
    

    All events and lifecycle method overrides can be async Task in Blazor, so you should be able to fit this in.