1
votes

Erreur de démarrage Blazor: System.Threading.SynchronizationLockException: impossible d'attendre sur les moniteurs sur ce runtime

J'essaie d'appeler une API pendant le démarrage de blazor (côté client) pour charger les traductions de langue dans ILocalizer.

Au moment où j'essaie d'obtenir le .Result du blazor de demande d'obtention, l'erreur dans le titre.

Cela peut être répliqué en appelant cette méthode dans le programme.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);
        }

    }


0 commentaires

3 Réponses :


2
votes

Évitez .Result , il peut facilement se bloquer. Vous obtenez cette erreur car le mécanisme n'est pas (ne peut pas être) pris en charge sur un assemblage Web à thread unique. Je considérerais cela comme une fonctionnalité. S'il pouvait attendre sur un moniteur, il gèlerait.

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

Tous les événements et substitutions de méthode de cycle de vie peuvent être une async Task dans Blazor, vous devriez donc pouvoir l'intégrer.


3 commentaires

Non, le code doit être appelé quelque part par une méthode asynchrone. J'ajouterais un OnInitAsync à App.razor.


ou dans la configuration DI


Peut-être que je ne connais pas de point asynchrone dans le flux là-bas.



3
votes

Dans Program.cs

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

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

    await host.RunAsync();

appelez votre code ici mais utilisez wait

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

    ......

    builder.Services.AddSingleton<SomeService>();

    var host = builder.Build();       

    ...


1 commentaires

bonne suggestion. Je pense qu'Ilocalizer n'est pas asynchrone mais ouais je pense que tu as raison, je devrai peut-être redresser le mien



0
votes

Ceci est un meilleur exemple:

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


0 commentaires