dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.34k stars 9.98k forks source link

Blazor WebAssembly Error : Cannot wait on monitors on this runtime. #26314

Closed nssidhu closed 4 years ago

nssidhu commented 4 years ago

I am making a call to GoogleMap GeoCode to get back the lat & Long for the given address.

var result = await JSRuntime.InvokeAsync("getIsInRange", address, range); Console.WriteLine("Recieved data " + result);

I am calling this from within loop for multiple address to be displayed in the table.

if i remove await the error goes away but than i don't get the lat & long since that it self is asyn on javascript side. What are my options here ?

crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: Cannot wait on monitors on this runtime.
System.Threading.SynchronizationLockException: Cannot wait on monitors on this runtime.
  at (wrapper managed-to-native) System.Threading.Monitor.Monitor_wait(object,int)
  at System.Threading.Monitor.ObjWait (System.Boolean exitContext, System.Int32 millisecondsTimeout, System.Object obj) <0x4ffe1b0 + 0x00046> in <filename unknown>:0 
  at System.Threading.Monitor.Wait (System.Object obj, System.Int32 millisecondsTimeout, System.Boolean exitContext) <0x4ffded0 + 0x00022> in <filename unknown>:0 
  at System.Threading.Monitor.Wait (System.Object obj, System.Int32 millisecondsTimeout) <0x4ffde08 + 0x0000a> in <filename unknown>:0 
  at System.Threading.ManualResetEventSlim.Wait (System.Int32 millisecondsTimeout, System.Threading.CancellationToken cancellationToken) <0x4ff34a0 + 0x001be> in <filename unknown>:0 
  at System.Threading.Tasks.Task.SpinThenBlockingWait (System.Int32 millisecondsTimeout, System.Threading.CancellationToken cancellationToken) <0x4ff1b30 + 0x00072> in <filename unknown>:0 
  at System.Threading.Tasks.Task.InternalWait (System.Int32 millisecondsTimeout, System.Threading.CancellationToken cancellationToken) <0x4ffd398 + 0x000ca> in <filename unknown>:0 
  at System.Threading.Tasks.Task`1[TResult].GetResultCore (System.Boolean waitCompletionNotification) <0x4ffd0f0 + 0x00024> in <filename unknown>:0 
  at System.Threading.Tasks.Task`1[TResult].get_Result () <0x4ffcfa8 + 0x00018> in <filename unknown>:0 
  at GetInLine.Client.Pages.Business.GetInLineUser+<>c__DisplayClass0_4.<BuildRenderTree>b__25 (Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder6) [0x00178] in C:\Users\nssidhu\source\repos\GetInLine\SikhSewa\Client\Pages\Business\GetInLineUser.razor:159 
  at Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder.AddContent (System.Int32 sequence, Microsoft.AspNetCore.Components.RenderFragment fragment) <0x3e50338 + 0x0001e> in <filename unknown>:0 
  at Radzen.Blazor.RadzenGrid`1+<>c__DisplayClass0_3[TItem].<BuildRenderTree>b__28 (Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder2) <0x4ff63a8 + 0x0072e> in <filename unknown>:0 
  at Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder.AddContent (System.Int32 sequence, Microsoft.AspNetCore.Components.RenderFragment fragment) <0x3e50338 + 0x0001e> in <filename unknown>:0 
  at Radzen.Blazor.RadzenGridRow.<BuildRenderTree>b__0_0 (Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder2) <0x4ff5af8 + 0x00026> in <filename unknown>:0 
  at Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder.AddContent (System.Int32 sequence, Microsoft.AspNetCore.Components.RenderFragment fragment) <0x3e50338 + 0x0001e> in <filename unknown>:0 
  at Microsoft.AspNetCore.Components.CascadingValue`1[TValue].Render (Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) <0x4ff5a10 + 0x00012> in <filename unknown>:0 
  at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch (Microsoft.AspNetCore.Components.Rendering.RenderBatchBuilder batchBuilder, Microsoft.AspNetCore.Components.RenderFragment renderFragment) <0x3ca4470 + 0x00062> in <filename unknown>:0 
  at Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderInExistingBatch (Microsoft.AspNetCore.Components.Rendering.RenderQueueEntry renderQueueEntry) <0x3ca3e70 + 0x0004c> in <filename unknown>:0 
  at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue () <0x3ca33a8 + 0x00098> in <filename unknown>:0 
pranavkm commented 4 years ago

Can you share a minimal app that reproduces the issue? We suspect the app must be making a blocking call (Task.Result) at some point to encounter this error.

nssidhu commented 4 years ago
@page "/"

<h1>Hello, world!</h1>
<table>
    <thead>
        <tr>
             <th>Number</th>
             <th>Multiple</th>
             <th>Total</th>
        </tr>
    </thead>

@foreach(KeyValuePair<int, int> num in Nums)
{
    <tr>
        <td>@num.Key</td>
        <td>@num.Value</td>
        <td>@GetMultiple(num.Key,num.Value).Result</td>
    </tr>

}
</table>
Welcome to your new app.

<SurveyPrompt Title="How is Blazor working for you?" />
<input type="button" @onclick="LoadData" value="LaodData"/>

@code{
    Dictionary<int, int> Nums = new Dictionary<int, int>();
    async Task LoadData()
    {
        Nums.Clear();
        Nums.Add(7, 2);
        Nums.Add(8, 2);
        Nums.Add(3, 2);
        Nums.Add(9, 2);
        Nums.Add(4, 2);
        StateHasChanged();
    }

    async Task<int> GetMultiple(int number, int multiplier)
    {
        try{

            await Task.Delay(20000);
            return number * multiplier;

        }
        catch(Exception e)
        {
            return - 1;
        }

    }
}
nikonthethird commented 4 years ago

I suspect this is exactly what @pranavkm meant:

<td>@GetMultiple(num.Key,num.Value).Result</td>

You are using .Result here, which is attempting to block the thread. This will not work on Blazor. Instead, try fetching the data into a variable that you display, and once the result arrives, call StateHasChanged(), which will update the view.

captainsafia commented 4 years ago

Thanks @nikonthethird.

As an additional note, you'll want to do this in a lifecycle method like OnInitializedAsync. You don't need to call StateHasChanged since Blazor will take care of that for you.