Search code examples
blazorblazor-server-side

Blazor page is disposing right after rendering


When implementing IDisposable in a blazor page (it can be @page "/" without any content) and setting a breakpoint in Dispose(), the method is called right after the application start. Is this a bug? How can I prevent this from happening?

Update: I have received the correct answer in the Blazor Discord Forum. I am updating the question for anyone who might struggle with the same issue, then there is at least one place on SO where you can find this.

As the comments and answers clearly show, there are several rendering modes in Blazor. When you use server side blazor, there is still a pre-rendering step being carried out. What for I have no idea and I didn't find either a reference to how you should use it or how you could detect while rendering whether you prerender. There are a few hacks which can be found, but they involve accessing of implementation detail, for instance to see if the JS Runtime has been initialized.

Solution: The proper solution was given to me in the Discord forum referencing this blog post: https://chrissainty.com/blazor-in-dotnet-8-server-side-and-streaming-rendering/. In here you can see that there is an attribute

[StreamRendering]

which can be put on your view. This indicates to blazor that you are using SSR streaming and then Dispose is not called. Thanks to @tesy for replying to my quesiton there.


Solution

  • This is intended behaviour and not a bug. You just don't yet have the knowledge to understand what's happening and the consequences of the options you chose in the solution template.

    You need to read the documentation here:

    According to the docs, there should be no pre-rendering for Server.

    Which bit of the docs are you referring to?

    You have configured your project with Interactivity set to Per Page/Component which means that each page is initially prerendered on the server.

    If you set Interactivity to Global only the first page is pre-rendered.

    Change App.Razor

        <HeadOutlet />
    </head>
    
    <body>
        <Routes />
        <script src="_framework/blazor.web.js"></script>
    </body>
    

    To this:

        <HeadOutlet @rendermode="@InteractiveServer" />
    </head>
    
    <body>
        <Routes @rendermode="@InteractiveServer" />
        <script src="_framework/blazor.web.js"></script>
    

    Or turn it off entirely:

        <HeadOutlet @rendermode="new InteractiveServerRenderMode(prerender: false)" />
    </head>
    
    <body>
        <Routes @rendermode="new InteractiveServerRenderMode(prerender: false)" />
        <script src="_framework/blazor.web.js"></script>