Обектът се изхвърля твърде рано?

Това ме озадачава. Имам този междинен софтуер 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));

        }
    }

и след това стартиращ клас:

   public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.Use((context, next) =>
            {
                return Task.Run(() =>
                {
                }).ContinueWith(t => next());
            });

            app.Use<M1>();
        }
    }

Изпълнението на това хвърля ObjectDisposedException в M1:

Няма достъп до изхвърлен обект. Име на обект: „System.Net.HttpListenerRequest“.

Проследяване на стека:

в System.Net.HttpListenerRequest.CheckDisposed() в System.Net.HttpListenerRequest.GetKnownHeader(HttpRequestHeader заглавка) в System.Net.HttpListenerRequest.get_UserHostName() в Microsoft.Owin.Host.HttpListener.RequestProcessing.RequestHeadersDictionary.TryGetValue( ключ за низ, String[]& value) в Microsoft.Owin.HeaderDictionary.TryGetValue(String ключ, String[]& value) в Microsoft.Owin.Infrastructure.OwinHelpers.GetHeaderUnmodified(IDictionary2 headers, String key) at Microsoft.Owin.Infrastructure.OwinHelpers.GetHeader(IDictionary2 заглавки, String ключ) в Microsoft.Owin.Infrastructure.OwinHelpers. GetHost(IOwinRequest заявка) в Microsoft.Owin.OwinRequest.get_Host()

Ако премахна този анонимен междинен софтуер преди app.Use();, тогава не се хвърля изключение.

Грешно ли го правя?


person Evgeni    schedule 01.03.2014    source източник
comment
Какво се опитваш да направиш?   -  person theMayer    schedule 01.03.2014
comment
Изглежда, че имате достъп до context асинхронно, след като някаква логика в Owin се разпорежда с него. Не знам нищо за Оуин, но това ми изглежда като много заплетена логика.   -  person theMayer    schedule 01.03.2014
comment
Току-що започнах да го уча, но много прилича на Node/ExpressJS.   -  person Evgeni    schedule 01.03.2014


Отговори (1)


Трябва да използвате await вместо ContinueWith, за да избегнете връщането на контрола към owin pipeline преди изпълнението на междинния софтуер. Нещо като това:

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>();
        }
    }
}
person buddyspike28    schedule 16.03.2014