Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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);
        }

    }
like image 964
JKerny Avatar asked Aug 02 '20 01:08

JKerny


3 Answers

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.

like image 86
Henk Holterman Avatar answered Oct 22 '22 21:10

Henk Holterman


In Program.cs

 public static async Task Main(string[] args)
 {

    ......

    builder.Services.AddSingleton<SomeService>();

    var host = builder.Build();       

    ...

call your code here but use await

    var httpClient = host.Services.GetRequiredService<HttpClient>();
    string response = await httpClient.GetStringAsync(path);
    ...

    var someService = host.Services.GetRequiredService<SomeService>();
    someService.SomeProperty = response;

    await host.RunAsync();
like image 43
Brian Parker Avatar answered Oct 22 '22 22:10

Brian Parker


This is a example best:

var client= new ProductServiceGrpc.ProductServiceGrpcClient(Channel);
            category =  (await client.GetCategoryAsync(new GetProductRequest() {Id = id})).Category;

like image 1
Didier Restrepo Avatar answered Oct 22 '22 20:10

Didier Restrepo