使用BuildManager.CreateInstanceFromVirtualPath创建页面时,PageAsyncT
本文关键字:PageAsyncT BuildManager CreateInstanceFromVirtualPath 创建 使用 | 更新日期: 2023-09-27 18:10:49
我有一个页面,我添加了一个异步任务,使用Page.RegisterAsyncTask
。如果页面被正常访问,例如通过导航到"/foo"。Aspx",然后一切都按预期工作。应用程序有一些相当复杂的路由,在某些情况下,页面是由调用BuildManager.CreateInstanceFromVirtualPath("~/foo.aspx", typeof(Page)) as IHttpHandler
的处理程序创建的,然后在生成的处理程序上调用ProcessRequest
。在完成之前,页面似乎没有等待注册的任务完成。
在这种情况下,如何让页面等待异步任务完成?
复制示例:
TestPage.aspx:
<%@ Page Language="C#" AutoEventWireup="true" Inherits="WebApplication1.TestPage" Async="true" AsyncTimeout="60" MasterPageFile="~/Site.Master" %>
<asp:Content ContentPlaceHolderID="MainContent" runat="server">
<asp:Button Text="Do Stuff" OnClick="Button1_Click" ID="Button1" runat="server" />
<asp:Literal ID="ResultsLiteral" runat="server" />
<script runat="server">
protected void Button1_Click(object sender, EventArgs e)
{
RegisterAsyncTask(new PageAsyncTask(DoStuff));
}
async System.Threading.Tasks.Task DoStuff()
{
await System.Threading.Tasks.Task.Delay(5);
ResultsLiteral.Text = "Done";
}
</script>
</asp:Content>
TestHandler.cs
using System.Web;
using System.Web.Compilation;
using System.Web.Routing;
using System.Web.UI;
namespace WebApplication1
{
public class TestHandler : IHttpHandler
{
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(HttpContext context)
{
GetHttpHandler().ProcessRequest(context);
}
IHttpHandler GetHttpHandler(HttpContext context)
{
return BuildManager.CreateInstanceFromVirtualPath("~/TestPage.aspx", typeof(Page)) as IHttpHandler;
}
}
public class RouteHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext context)
{
return new TestHandler();
}
}
}
路由(在RouteConfig.cs中添加):
public static void RegisterRoutes(RouteCollection routes)
{
routes.Add(new Route("TestHandler", new RouteHandler()));
}
复制步骤:
- 导航到TestPage。Aspx,点击按钮&消息按预期出现导航到/TestHandler,你应该看到相同的页面,但是如果你点击按钮,消息不会出现。
您正在同步调用Page。您需要异步调用它,否则需要异步api,如Page。RegisterAsyncTask将不能正常工作。试试这样做:
public class TestHandler : IHttpAsyncHandler
{
private IHttpAsyncHandler _handler;
public bool IsReusable
{
get { return false; }
}
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback callback, object state)
{
_handler = GetHttpHandler(context);
return _handler.BeginProcessRequest(context, callback, state);
}
public void EndProcessRequest(IAsyncResult asyncResult)
{
_handler.EndProcessRequest(asyncResult);
}
public void ProcessRequest(HttpContext context)
{
throw new NotSupportedException();
}
IHttpAsyncHandler GetHttpHandler(HttpContext context)
{
return BuildManager.CreateInstanceFromVirtualPath("~/TestPage.aspx", typeof(Page)) as IHttpAsyncHandler;
}
}