我在ASP.NET WebApi2设置中遇到了一些OWIN的困难.重启后的第一个请求导致异常:
[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
我认为问题是由于第一次点击EF DbContext时长时间运行的任务造成的.总而言之,第一个请求大约是4-6000毫秒.在第一次请求之后,没有更多例外.
我已经使用webapi项目和以下OWIN启动(并且没有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); } }
我添加一个控制器:
[Route("api/test/number")] public class TestController : ApiController { public object Get() { return 42; } }
当我请求这个时,第一个请求导致异常.
解决方法
这是一个老问题,但是花了好几个小时试图击败ObjectDisposedException并找到了一个解决方案,这个
AspNetWebStack issue on codeplex帮助了我:
当您的owin web api应该在自托管环境中运行时,您可以在owin启动类中绑定web api配置
public void Configuration(IAppBuilder app) { ConfigureOAuth(app); HttpConfiguration config = new HttpConfiguration(); WebApiConfig.Register(config); app.UseWebApi(config); }
如果您打算使用IIS作为您的owin web api的主机,那么将web api配置绑定到全局asax类中
protected void Application_Start(object sender,EventArgs e) { GlobalConfiguration.Configure(WebApiConfig.Register); }
这消除了ObjectDisposedException,我的web api像魅力一样运行