Web API with OWIN throws ObjectDisposedException f

2019-02-12 19:30发布

I am having some difficulties with OWIN in a ASP.NET WebApi2 setting. The first request after a restart results in the exception:

    [ObjectDisposedException: Cannot access a disposed object.
    Object name: 'System.Net.Http.HttpMessageInvoker'.]
       System.Net.Http.HttpMessageInvoker.CheckDisposed() +327456
       System.Net.Http.HttpMessageInvoker.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) +24
       System.Web.Http.Owin.<InvokeCore>d__0.MoveNext() +501
       System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +99
       System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
       Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.<RunApp>d__5.MoveNext() +187
       System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +99
       System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
       Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.<DoFinalWork>d__2.MoveNext() +185
       Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.StageAsyncResult.End(IAsyncResult ar) +69
       Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork(IAsyncResult ar) +64
       System.Web.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +483
       System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +157
    
I believe the problem is caused by a long running task when its hitting the EF DbContext for the first time. All in all the first request is around 4-6000ms. After this first request there are no more exceptions.

I have reproduced the issue in a simplified form with a webapi project and the following OWIN startup (and no global.asax):

public class Startup
{
    public void Configuration(IAppBuilder app) {
        var config = new HttpConfiguration();
        config.MapHttpAttributeRoutes();

        // ---- simulate long running initialization code -------
        Thread.Sleep(3000);
        // ------------------------------------------------------

        app.UseWebApi(config);
    }
}

I add a controller:

[Route("api/test/number")]
public class TestController : ApiController
{
    public object Get() {
        return 42;
    }
}

When I request this the first request results in the exception.

1条回答
戒情不戒烟
2楼-- · 2019-02-12 20:00

This is an old question but a just spent hours trying to beat the ObjectDisposedException and just found a solution which this AspNetWebStack issue on codeplex helped me with:

When your owin web api should run in self-hosting environments you bind the web api config in the owin startup class

public void Configuration(IAppBuilder app)
{
    ConfigureOAuth(app);

    HttpConfiguration config = new HttpConfiguration();
    WebApiConfig.Register(config);
    app.UseWebApi(config);
}

If you intend to use IIS as host for your owin web api then bind the web api config in the global asax class

protected void Application_Start(object sender, EventArgs e)
{
    GlobalConfiguration.Configure(WebApiConfig.Register);
}

This eliminated the ObjectDisposedException and my web api runs like a charm

查看更多
登录 后发表回答