【发布时间】:2017-02-06 17:57:50
【问题描述】:
在之前的 question 的基础上,我在 middleware 的 Configure 方法中拦截传入请求。
public class Startup: IStartup
{
public Startup(IHostingEnvironment environment)
{
// starting apparatus
}
public void Configure(IApplicationBuilder app)
{
var self = this;
app.Run(async (context) =>
{
await self.Delegate.Service(context);
});
}
public void output(HttpContext context string output)
{
context.Response.WriteAsync(output);
}
// other methods
public IRouter Delegate { get; set; }
}
处理程序
public class Handler: IRouter
{
public void Service(HttpContext context)
{
// shuttles the context to the other parts of the system
// for processing data
}
public void ServiceResult(HttpContext context, object result)
{
// system calls this method, which is then passed back to Startup object.
Startup.output(context, result);
}
}
启动应该将上下文交给处理程序来处理请求。
Handler 然后分派到系统的另一部分,在该部分中根据 URI 处理请求。处理完成后,其他部分将调用 ServerResult。
基本上,工作流是
Startup将上下文委托给设备,并且设备将上下文与输出结果一起返回。断开连接,输出将发生在另一个函数/闭包/lambda中,但不是同一个中间件。
我被这个中间件阻止了,它迫使我等待并将其定义为异步,关于如何在 asp.net 核心世界中实现上述内容的任何进一步建议。
P.S. 请求拦截可以在任何地方发生,我不必像我的示例那样在中间件中进行。
P.P.S 一个想法可能是 Startup 可以将 lambda 传递给设备,然后一旦请求完成处理,设备就可以调用该设备。
我的尝试:
启动
public void Configure(IApplicationBuilder app)
{
var self = this;
app.Run(async (context) =>
{
await self.Handler.Handle(new Request(context, new Task(() => { })));
});
}
public void Result(Request request)
{
request.Context.Response.WriteAsync(request.Result); // write the result
request.Task.Start(); // end waiting for the middleware async
}
处理程序
public Task Handle(Request request)
{
// delegates to helper objects to process the request
return request.Task;
}
public void Result(Request request)
{
// helper objects called this function after populating results
startup.Result(request);
}
【问题讨论】:
-
假设中间件不会等待内容,这将如何工作? “处理程序”可以在任何随机时刻返回,在任何可能的时刻写入输出并放置在生成的 HTML 中……或者更糟糕的是,它可能会在响应已经发送时尝试写入。 – 如果你有一个不基于任务的异步机制(使用
async和await)——无论出于何种原因——那么你需要将它转换为一个以正确使用它。 -
好的,我看到中间件必须等待,因此可以将 lambda 从 Startup 传递到库,库处理并输出数据,然后最终调用此 lambda 以完成序列。请参阅“使用路由中间件”下的配置方法以获取任何想法。 docs.microsoft.com/en-us/aspnet/core/fundamentals/routing
-
您似乎误解了 lambda 是什么。他们只是匿名代表。请注意,这 不是 JavaScript,并且没有异步事件循环。 – 是的,您可以传递一个 lambda,它会在一切完成后被调用,但这不会使进程神奇地异步。如果你想要异步,你必须明确地做到这一点。
-
好的,我正在工作,正在重构处理程序以返回任务,将在我取得进展时编辑我的问题。
-
所以你的问题是你的 Handler 是同步的,但是 app.Run 需要异步委托?
标签: c# asp.net-core