-
Notifications
You must be signed in to change notification settings - Fork 9.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
await inside OnInitAsync causes the browser to hang #15463
Comments
You have to understand that await in async method means "if the task is not completed temporarily suspend execution of this function and return to the caller (in this case Blazor runtime)". Blazor calls your OnInitAsync method and renders your page first time immediately after first suspension. Then it renders your page again when your method finishes. Run this code and watch the screen. Then comment first @page "/"
<div>
@if (Items == null)
{
<div>List not initialized yet.</div>
}
else
{
@foreach (var item in Items)
{
<div>@item</div>
}
}
</div> @functions {
List<int> Items { get; set; }
protected override async Task OnInitAsync()
{
await Task.Delay(1000);
//await Task.CompletedTask;
Items = new List<int>();
Items.Add(1);
await Task.Delay(1000);
Items.Add(2);
await Task.Delay(1000);
Items.Add(3);
}
} |
try instantiate a new instance of Items first
|
@thewebchameleon your solution is based on some Blazor implementation detail and if you really want to create a new List instance before the page is rendered the first time you can simply move this line above the first List<int> Items { get; set; } = new List<int>(); Both solutions are in my opinion much better than a new function override. The most important fact to remember is: each time Blazor calls your async method your page can be rendered two times and your rendering code have to be prepared for this. This is true not only in OnInitAsync but also in all other async methods, for example in button's onclick event. |
Thank you all for your quick response. I was wondering if this behavior was by-design but it looked bad enough that I thought it wasn't. Finding aspnet/Blazor#1242 didn't help either. Is there any chance you could include this explanation in the documentation. I went through a lot and couldn't find a single mention of this behavior, plus all the examples I could find are simplistic and don't attempt to load data asynchronously which is realistic and what I was trying to do:
Keep up the great work. Blazor is an amazing idea! |
Similar to aspnet/Blazor#1242 but I can consistently reproduce and it happens on the simplest Component. No Layout involved. Happened on 0.6.0 and kept happening after I upgraded to 0.7.0.
It is a very strange behavior which points to some mishandling of asynchronous actions inside OnInitAsync.
Version that behaves as expected
The code below fails as expected. A System.NullReferenceException is shown in the browser console.
Result:
Uncaught (in promise) Error: System.NullReferenceException: Object reference not set to an instance of an object.
Version that works as expected
Result: item1 is shown on the screen.
Version that unexpectedly hangs up
Result: An exception is shown in the console (which I wasn't expecting), and from that point on the browser becomes unresponsive and I need to close the tab and re-run the Blazor application.
Uncaught (in promise) Error: System.NullReferenceException: Object reference not set to an instance of an object.
The text was updated successfully, but these errors were encountered: