Owin.AppBuilderExtensions中的内存泄漏

Dmi*_*mov 20 c# owin asp.net-identity

我在Web应用程序中使用OWIN + Microsoft.AspNet.Identity.Owin(v.2.0.0.0).我按照广泛推荐的方式为每个Web请求注册UserManager/DbContext:

app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
Run Code Online (Sandbox Code Playgroud)

但都没有处理过.我瞥了一眼反射器,看起来像扩展方法中的一个bug:

public static IAppBuilder CreatePerOwinContext<T>(this IAppBuilder app, Func<IdentityFactoryOptions<T>, IOwinContext, T> createCallback) where T: class, IDisposable
{
    if (app == null)
    {
        throw new ArgumentNullException("app");
    }
    if (createCallback == null)
    {
        throw new ArgumentNullException("createCallback");
    }
    object[] args = new object[1];
    IdentityFactoryOptions<T> options = new IdentityFactoryOptions<T> {
        DataProtectionProvider = app.GetDataProtectionProvider()
    };
    IdentityFactoryProvider<T> provider = new IdentityFactoryProvider<T> {
        OnCreate = createCallback
    };
    options.Provider = provider;
    args[0] = options;
    app.Use(typeof(IdentityFactoryMiddleware<T, IdentityFactoryOptions<T>>), args);
    return app;
}
Run Code Online (Sandbox Code Playgroud)

IdentityFactoryProvider有两个回调 - 创建和dispose,但是这里没有注册dispose回调.我也证实了我对记忆探测器的怀疑.

我没有在codeplex/github上看到Owin(实际上我认为它是开源的),所以我不知道在哪里问我的问题:还有其他人可以确认这是内存泄漏吗?我不确定,因为谷歌没有说它,我希望它应该在任何地方讨论,如果这是一个错误.

Sha*_*zza 6

我也有他的问题,没有任何注册的CreatePerOwinContext被处置.我正在使用v2.1.

这是一个临时修复,对我来说很有效,直到修复了这个lib.您基本上必须在以下类中手动注册使用Register与CreatePerOwnContext的每个类型,然后在启动过程结束时注册此自定义类:

public sealed class OwinContextDisposal : IDisposable
{
    private readonly List<IDisposable> _disposables = new List<IDisposable>(); 

    public OwinContextDisposal(IOwinContext owinContext)
    {
        if (HttpContext.Current == null) return;

        //TODO: Add all owin context disposable types here
        _disposables.Add(owinContext.Get<MyObject1>());
        _disposables.Add(owinContext.Get<MyObject2>());

        HttpContext.Current.DisposeOnPipelineCompleted(this);
    }

    public void Dispose()
    {
        foreach (var disposable in _disposables)
        {
            disposable.Dispose();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,您的启动过程会注册此类:

 app.CreatePerOwinContext<OwinContextDisposal>(
      (o, c) => new OwinContextDisposal(c));
Run Code Online (Sandbox Code Playgroud)

现在一切都将在请求管道的末尾正确处理掉.


Joz*_*ský 5

AppBuilderExtensions类的内存泄漏已在最新版本的Microsoft.AspNet.Identity.Owin库(2.2.1)中修复.

我已经使用Reflector检查了代码,并将断点放入Dispose()由对象创建的对象的方法中AppBuilderExtensions.CreatePerOwinContext().