以之前的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);
}
}
启动应将上下文移交给处理程序以处理请求。
然后,处理程序将调度到基于URI处理请求的系统的另一部分。处理完成后,其他部分将调用ServerResult。
基本上工作流是Startup
委托设备和设备的上下文返回上下文以及输出结果。如果有断开连接,输出将在另一个函数/ closure / 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);
}
答案 0 :(得分:1)
我不是说这是最好的方式,但由于你缺乏经验并完成工作 - 你可以使用TaskCompletionSource
:
public class Handler {
private TaskCompletionSource<string> _tcs;
public Task<string> Start(HttpContext context) {
_tcs = new TaskCompletionSource<string>();
// shuttles the context to the other parts of the system
// for processing data
return _tcs.Task;
}
private void Complete(string output) {
if (_tcs == null)
throw new Exception("Task has not been started yet");
// system calls this method, which is then passed back to Startup object.
_tcs.SetResult(output);
}
}
public void Configure(IApplicationBuilder app) {
app.Run(async (context) => {
var output = await new Handler().Start(context);
await context.Response.WriteAsync(output);
});
}