Search code examples
blazorblazor-webassembly

The ParameterView instance can no longer be read because it has expired. ParameterView can only be read synchronously and must not be stored for


When overriding SetParametersAsync, if I call any asynchronous method then I get the "Unhandled exception rendering component: The ParameterView instance can no longer be read because it has expired. ParameterView can only be read synchronously and must not be stored for later use."

public override async Task SetParametersAsync(ParameterView parameters)
{
    await Task.Delay(1000);

    await base.SetParametersAsync(parameters);
}

How can we safely call an async method in SetParamatersAsync?


Solution

  • I believe the coding patterns you're looking for are shown below. The error message is generated by the Renderer. It's passing in the ParameterView, tracks it, and expects it to be consumed immediately (synchronously). The parameters within the object could be very stale in a second.

    In the pattern we consume parameters immediately, applying it to the component instance properties. We can then call base at our leisure, passing an empty ParameterView as we've already set them.

            public async override Task SetParametersAsync(ParameterView parameters)
            {
                parameters.SetParameterProperties(this);
                await Task.Delay(100);
                await base.SetParametersAsync(ParameterView.Empty);
            }
    
            public override Task SetParametersAsync(ParameterView parameters)
            {
                parameters.SetParameterProperties(this);
                  ... Do things
                return base.SetParametersAsync(ParameterView.Empty);
            }
    

    This is the pattern the ASPNetCore team seem to use. You can see it here in the code for InputBase - line 190 onwards.