这让我很困惑。我有这个OWIN / Katana中间件:
class M1 : OwinMiddleware
{
public M1(OwinMiddleware next) : base(next) { }
public override Task Invoke(IOwinContext context)
{
return Task.Run(() =>
{
Thread.Sleep(200); ; // do something
string reqUrl = context.Request.Uri.ToString(); //<- throws exception
})
.ContinueWith(t => this.Next.Invoke(context));
}
}
然后是一个Startup类:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.Use((context, next) =>
{
return Task.Run(() =>
{
}).ContinueWith(t => next());
});
app.Use<M1>();
}
}
运行它会在M1中抛出ObjectDisposedException:
无法访问已处置的对象。对象名称: 'System.Net.HttpListenerRequest'。
堆栈追踪:
在System.Net.HttpListenerRequest.CheckDisposed()处 System.Net.HttpListenerRequest.GetKnownHeader(HttpRequestHeader 头部)在System.Net.HttpListenerRequest.get_UserHostName()处 Microsoft.Owin.Host.HttpListener.RequestProcessing.RequestHeadersDictionary.TryGetValue(字符串 key,String []&amp;价值) Microsoft.Owin.HeaderDictionary.TryGetValue(String key,String []&amp; 价值) Microsoft.Owin.Infrastructure.OwinHelpers.GetHeaderUnmodified(IDictionary的
2 headers, String key) at Microsoft.Owin.Infrastructure.OwinHelpers.GetHeader(IDictionary
2 header,String key)at Microsoft.Owin.Infrastructure.OwinHelpers.GetHost(IOwinRequest 请求)在Microsoft.Owin.OwinRequest.get_Host()
如果我在 app.Use(); 之前删除该匿名中间件,则不会抛出任何异常。
我做错了吗?
答案 0 :(得分:1)
您应该使用await而不是ContinueWith来避免在执行中间件之前将控制权返回给owin管道。像这样:
class M1 : OwinMiddleware
{
public M1(OwinMiddleware next) : base(next) { }
public override async Task Invoke(IOwinContext context)
{
await Task.Run(() =>
{
Thread.Sleep(200); ; // do something
string reqUrl = context.Request.Uri.ToString(); //<- throws exception
});
await this.Next.Invoke(context);
}
}
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.Use(async (context, next) =>
{
await Task.Run(() => { });
await next();
});
app.Use<M1>();
}
}
}