Owin 中间件 return 的响应能否早于 Invoke 方法 return?
Can an Owin Middleware return a response earlier than the Invoke method returns?
我有以下中间件代码:
public class UoWMiddleware : OwinMiddleware
{
readonly IUoW uow;
public UoWMiddleware(OwinMiddleware next, IUoW uow) : base(next)
{
this.uow = uow;
}
public override async Task Invoke(IOwinContext context)
{
try
{
await Next.Invoke(context);
}
catch
{
uow.RollBack();
throw;
}
finally
{
if (uow.Status == Base.SharedDomain.UoWStatus.Running)
{
var response = context.Response;
if (response.StatusCode < 400)
{
Thread.Sleep(1000);
uow.Commit();
}
else
uow.RollBack();
}
}
}
}
偶尔我们观察到在通过 fiddler 调用 uow.Commit() 之前对客户端的响应 returns。例如,我们在 uow.Commit 上设置了一个断点,尽管我们正在断点等待,但我们看到响应已 returned 到客户端。这有些出乎意料。我认为在 Invoke 方法结束后响应将严格 return 。我错过了什么吗?
在 Owin/Katana 中,当中间件调用 Write
时,响应 body(当然还有 headers)被发送到客户端Response
object 的 IOwinContext
.
这意味着如果您的 next 中间件正在写入响应 body 您的客户端将在您的 server-side 代码 returns 之前收到它调用 await Next.Invoke()
.
这就是 Owin 的设计方式,并且取决于响应流可能在单个 Request/Response life-cycle.
中仅写入一次这一事实
查看您的代码,我看不出这种行为有任何重大问题,因为您只是在将响应写入流后读取响应 headers,因此不会更改它。
相反,如果您需要更改下一个中间件编写的响应,或者您严格需要在 执行进一步逻辑 server-side 之后编写响应 ,那么你唯一的选择是将响应 body 缓冲到内存流中,然后在准备好时将其复制到真正的响应流 (as per this answer) 中。
我已经在不同的用例(但共享相同的概念)中成功测试了这种方法,您可能会在查看此答案时发现:https://whosebug.com/a/36755639/3670737
我有以下中间件代码:
public class UoWMiddleware : OwinMiddleware
{
readonly IUoW uow;
public UoWMiddleware(OwinMiddleware next, IUoW uow) : base(next)
{
this.uow = uow;
}
public override async Task Invoke(IOwinContext context)
{
try
{
await Next.Invoke(context);
}
catch
{
uow.RollBack();
throw;
}
finally
{
if (uow.Status == Base.SharedDomain.UoWStatus.Running)
{
var response = context.Response;
if (response.StatusCode < 400)
{
Thread.Sleep(1000);
uow.Commit();
}
else
uow.RollBack();
}
}
}
}
偶尔我们观察到在通过 fiddler 调用 uow.Commit() 之前对客户端的响应 returns。例如,我们在 uow.Commit 上设置了一个断点,尽管我们正在断点等待,但我们看到响应已 returned 到客户端。这有些出乎意料。我认为在 Invoke 方法结束后响应将严格 return 。我错过了什么吗?
在 Owin/Katana 中,当中间件调用 Write
时,响应 body(当然还有 headers)被发送到客户端Response
object 的 IOwinContext
.
这意味着如果您的 next 中间件正在写入响应 body 您的客户端将在您的 server-side 代码 returns 之前收到它调用 await Next.Invoke()
.
这就是 Owin 的设计方式,并且取决于响应流可能在单个 Request/Response life-cycle.
中仅写入一次这一事实查看您的代码,我看不出这种行为有任何重大问题,因为您只是在将响应写入流后读取响应 headers,因此不会更改它。
相反,如果您需要更改下一个中间件编写的响应,或者您严格需要在 执行进一步逻辑 server-side 之后编写响应 ,那么你唯一的选择是将响应 body 缓冲到内存流中,然后在准备好时将其复制到真正的响应流 (as per this answer) 中。
我已经在不同的用例(但共享相同的概念)中成功测试了这种方法,您可能会在查看此答案时发现:https://whosebug.com/a/36755639/3670737