gpt4 book ai didi

c# - ASP.NET Core MVC 异步加载 session

转载 作者:太空宇宙 更新时间:2023-11-03 12:29:47 26 4
gpt4 key购买 nike

我一直在看官方Session and application state文档并偶然发现了以下段落:

Loading Session asynchronously

The default session provider in ASP.NET Core loads the session record from the underlying IDistributedCache store asynchronously only if the ISession.LoadAsync method is explicitly called before the TryGetValue, Set, or Remove methods. If LoadAsync is not called first, the underlying session record is loaded synchronously, which could potentially impact the ability of the app to scale.

To have applications enforce this pattern, wrap the DistributedSessionStore and DistributedSession implementations with versions that throw an exception if the LoadAsync method is not called before TryGetValue, Set, or Remove. Register the wrapped versions in the services container.

包装本身对我来说不是问题,但为了实现它,我需要:

  1. 引用原始实现
  2. 注册封装版本

目前,我已经创建了以下包装类:

public class WrappedDistributedSession : ISession
{
private DistributedSession _service;
private bool loaded = false;

public WrappedDistributedSession(DistributedSession service)
{
_service = service;
}

public bool IsAvailable => _service.IsAvailable;

public string Id => _service.Id;

public IEnumerable<string> Keys => _service.Keys;

public void Clear() => _service.Clear();

public Task CommitAsync() => _service.CommitAsync();

public Task LoadAsync()
{
loaded = true;
return _service.LoadAsync();
}

public void Remove(string key)
{
if(loaded)
{
_service.Remove(key);
} else
{
throw new Exception();
}
}

public void Set(string key, byte[] value)
{
if (loaded)
{
_service.Set(key, value);
}
else
{
throw new Exception();
}
}

public bool TryGetValue(string key, out byte[] value)
{
if (loaded)
{
return _service.TryGetValue(key, out value);
}
else
{
throw new Exception();
}
}
}

并且我已经在Startup.ConfigureServices中注册了它

services.AddScoped<ISession, WrappedDistributedSession>();

显然,由于我正在写这个问题,所以我的解决方案不起作用。我哪里出错了,如何“在服务容器中注册包装版本”?

最佳答案

使用风险自负。这似乎在 session 之后的 Configure 方法中起作用。此解决方案改编自此单元测试: https://github.com/dotnet/aspnetcore/blob/cd0eab88eaa230fa276c27ab5dc71ea267efe14f/src/Middleware/Session/test/SessionTests.cs#L654-L656

 app.UseSession();
app.Use(async (context, next) =>
{
await context.Session.LoadAsync();
await next();
});

或者作为一个更合格的包装器扩展:

public static class SesssionAsyncExtensions
{
/// <summary>
/// Have sessions be asyncronous. This adaptation is needed to force the session provider to use async calls instead of syncronous ones for session.
/// Someone surprisingly for something that seems common, Microsoft didn't make this aspect super nice.
/// </summary>
/// <param name="app">App builder instance.</param>
/// <returns>App builder instance for chaining.</returns>
/// <remarks>
/// From Microsoft Documentation (https://learn.microsoft.com/en-us/aspnet/core/fundamentals/app-state?view=aspnetcore-5.0):
/// The default session provider in ASP.NET Core will only load the session record from the underlying IDistributedCache store asynchronously if the
/// ISession.LoadAsync method is explicitly called before calling the TryGetValue, Set or Remove methods.
/// Failure to call LoadAsync first will result in the underlying session record being loaded synchronously,
/// which could potentially impact the ability of an application to scale.
///
/// See also:
/// https://github.com/dotnet/aspnetcore/blob/d2a0cbc093e1e7bb3e38b55cd6043e4e2a0a2e9a/src/Middleware/Session/src/DistributedSession.cs#L268
/// https://github.com/dotnet/AspNetCore.Docs/issues/1840#issuecomment-454182594
/// https://bartwullems.blogspot.com/2019/12/aspnet-core-load-session-state.html
/// </remarks>
public static IApplicationBuilder UseAsyncSession(this IApplicationBuilder app)
{
app.UseSession();
app.Use(async (context, next) =>
{
await context.Session.LoadAsync();
await next();
});
return app;
}
}

关于c# - ASP.NET Core MVC 异步加载 session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43201763/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com