Open Bouke opened 1 year ago
I'm not sure how that would work. The request isn't being re-run when StateHashChanged
fires. This isn't about async locals as much as its about where the async locals are being set. In the above case, the middleware isn't being re-run so it's by design that the value doesn't change.
The problem is that the value of AsyncLocal
is expected to stay the same for the duration of the circuit, once set from the middleware. The render triggered by hot reload is rendered with different AsyncLocal
(null values), however on subsequent renders the original AsyncLocal
values are back. So I'm thinking that the render triggered by hot reload is executed from the wrong ExecutionContext
.
I've updated the title to reflect the issue. This does sound like a bug. I assume it's coming from somewhere here
The execution context needs to be captured at the location where the delegate is being registered here and the callback needs to be dispatched to that context.
With that in mind, I would avoid relying on AsyncLocals set inside middleware, as they won't survive re-connection. The right approach to work with async locals in Blazor is covered https://github.com/dotnet/AspNetCore.Docs/pull/27909/files?short_path=e2a9b3d#diff-e2a9b3d2f3c263585acc721fd569aa0a0666144e4e9bbbf5673e8e53c007749e (can't find the link to the actual docs).
Thanks for contacting us.
We're moving this issue to the .NET 8 Planning
milestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s).
If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues.
To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.
With that in mind, I would avoid relying on AsyncLocals set inside middleware, as they won't survive re-connection.
This issue is not about AsyncLocals in middleware. It is about AsyncLocal in Blazor. The middleware sets the AsyncLocal (the current culture), and the Blazor components gets the AsyncLocal.
nl
)nl
)en-US
)nl
)The right approach to work with async locals in Blazor is covered https://github.com/dotnet/AspNetCore.Docs/pull/27909/files?short_path=e2a9b3d#diff-e2a9b3d2f3c263585acc721fd569aa0a0666144e4e9bbbf5673e8e53c007749e (can't find the link to the actual docs).
Link to docs: https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/dependency-injection?view=aspnetcore-7.0#access-blazor-services-from-a-different-di-scope. I fail to see how this applies to this issue though? Getting/setting the current culture is just an example of AsyncLocal
in combination with hot reload: it only fails for hot reload. Having to rewrite core runtime functionality using AsyncLocal
such as CultureInfo.CurrentCulture
in an ad-hoc manner to be blazor-compatible (and consequently all my blazor un-aware services) seems the wrong approach to me.
Thanks for contacting us.
We're moving this issue to the .NET 9 Planning
milestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s).
If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues.
To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.
blazor web app .net8
public class AbpExceptionInterceptor1
{
public static readonly AsyncLocal<IServiceProvider> Services = new AsyncLocal<IServiceProvider>();
}
in routers component
[Inject]
public IServiceProvider ServiceProvider { get; set; }
protected override void OnInitialized()
{
AbpExceptionInterceptor1.Services.Value = ServiceProvider;
//...
why the AbpExceptionInterceptor1.Services always null.I am using Fody based AOP and particularly need such functionality.
Thank you again for the asp.net core blazer!
Is there an existing issue for this?
Describe the bug
When a hot reload is performed, any value stored with
AsyncLocal
is not available on the first render. Any subsequent renders will have the originalAsyncLocal
values available again.AsyncLocal
is a common design approach for storing contextual information, e.g.Thread.CurrentPrincipal
orCultureInfo.CurrentCulture
as set byapp.UseRequestLocalization()
.Expected Behavior
AsyncLocal
should flow and also be available on the rerender triggered by hot reload.Steps To Reproduce
https://github.com/Bouke/BlazorAsyncLocal/commit/640aeb50a77e26e5bef38556d8d4e6147de5ac7b Or:
Run
dotnet watch
and open in browser. Notice that the page says:Change
Pages/Index.razor
in a way that triggers hot reload. E.g. change the heading to<h1>Hello, you!</h1>
Notice that the page now says:
Click the button labeled "Invoke StateHasChanged()". Notice that the page now updates to the text from step 2:
Exceptions (if any)
No response
.NET Version
6.0.403
Anything else?
.NET SDK (reflecting any global.json): Version: 6.0.403 Commit: 2bc18bf292
Runtime Environment: OS Name: Mac OS X OS Version: 13.1 OS Platform: Darwin RID: osx-x64 Base Path: /usr/local/share/dotnet/sdk/6.0.403/
global.json file: Not found
Host: Version: 6.0.11 Architecture: x64 Commit: 943474ca16
.NET SDKs installed: 6.0.403 [/usr/local/share/dotnet/sdk]
.NET runtimes installed: Microsoft.AspNetCore.App 6.0.11 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.NETCore.App 6.0.11 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]