C# 从ASP.Net调用异步函数

C# 从ASP.Net调用异步函数,c#,asp.net,async-await,impersonation,C#,Asp.net,Async Await,Impersonation,在一个ASP.Net项目中,我最近将一些冗长的函数改为async。事实证明,这导致了一些未完成的问题 基本上,当使用await时,函数可以工作,但是必须从另一个异步函数调用它最终会成为表单中的一个问题。 到目前为止,我将page指令Async设置为true,并使用RegisterAsyncTask启动对异步函数的调用。电话响了。但事实证明,当我启用异步页面指令时,用户上下文有时会发生变化 为了强制调用用户执行某些页面中的所有代码,我将类System.Web.UI.Page继承到Impersona

在一个ASP.Net项目中,我最近将一些冗长的函数改为async。事实证明,这导致了一些未完成的问题

基本上,当使用await时,函数可以工作,但是必须从另一个异步函数调用它最终会成为表单中的一个问题。 到目前为止,我将page指令Async设置为true,并使用RegisterAsyncTask启动对异步函数的调用。电话响了。但事实证明,当我启用异步页面指令时,用户上下文有时会发生变化

为了强制调用用户执行某些页面中的所有代码,我将类System.Web.UI.Page继承到ImpersonatedPage。在我的类中,我使用OnLoad来导入调用用户。通过这种方式,我确信用户再也看不到或做不到他/她已经可以访问的内容了,并且审核日志显示了正确的用户

当启用Async page指令时,它仍然模拟用户。但例如,在单击按钮的代码中,用户上下文会突然返回到应用程序池上下文。在页面加载中,用户上下文是预期的调用用户。 这是什么原因造成的?是否可以避免切换回应用程序池用户

或者,我尝试删除Async page指令,并使用Task.Run调用Async函数。然后用户上下文不会切换回来,而是HttpContext.Current为null,并且异步函数无法完成它的工作

从ASP.Net调用异步函数而不必启用async page指令还有其他方法吗

目标框架:4.6.1 AFAIK未启用任何怪癖

模拟页面类:

public class ImpersonatedPage : System.Web.UI.Page
{
    WindowsImpersonationContext m_wic = null;

    protected override void OnLoad(EventArgs e)
    {
        WindowsIdentity wi = (WindowsIdentity)System.Web.HttpContext.Current.User.Identity;
        m_wic = wi.Impersonate();
        HttpContext.Current.Response.Write("Impersonate<br />");
        base.OnLoad(e);
    }

    protected override void OnUnload(EventArgs e)
    {
        base.OnUnload(e);
        _ImpersonationUndo();
    }

    protected void _ImpersonationUndo()
    {
        if (m_wic != null)
        {
            m_wic.Undo();
            HttpContext.Current.Response.Write("Impersonate undo<br />");
        }
        m_wic = null;
    }
}
页面加载:

protected void Page_Load(object sender, EventArgs e)
{
    Response.Write("Page_Load: " + WindowsIdentity.GetCurrent().Name + "<br />");

    if (!IsPostBack)
    {
        RegisterAsyncTask(new PageAsyncTask(InitialPageLoadAsync));
    }
    ...
受保护的无效页面加载(对象发送方,事件参数e)
{
Write(“页面加载:+WindowsIdentity.GetCurrent().Name+”
); 如果(!IsPostBack) { RegisterAsyncTask(新页面异步任务(InitialPageLoadAsync)); } ...
异步函数:

private async Task InitialPageLoadAsync()
{
    Response.Write("InitialPageLoadAsync: " + WindowsIdentity.GetCurrent().Name + "<br />");

    await fnDoSomeAsyncWork();
    ...
专用异步任务InitialPageLoadAsync()
{
Write(“InitialPageLoadAsync:+WindowsIdentity.GetCurrent().Name+”
); 等待fnDoSomeAsyncWork(); ...
按钮点击:

protected void idBtnSaveSrv_Click(object sender, EventArgs e)
{
    Response.Write("idBtnSaveSrv_Click: " + WindowsIdentity.GetCurrent().Name + "<br />");
    ...
protectedvoid idBtnSaveSrv\u单击(对象发送方,事件参数e)
{
响应。写入(“idBtnSaveSrv_单击:“+WindowsIdentity.GetCurrent().Name+”
); ...
调试输出-初始请求:

  • 冒充
  • 页面\加载:域\我的用户
  • InitialPageLoadAsync:IIS APPPOOL\appuser(为什么?)
  • [网页内容]
  • 模拟撤消
调试输出-按钮单击:

protected void idBtnSaveSrv_Click(object sender, EventArgs e)
{
    Response.Write("idBtnSaveSrv_Click: " + WindowsIdentity.GetCurrent().Name + "<br />");
    ...
  • 冒充
  • 页面\加载:域\我的用户
  • idBtnSaveSrv_单击:IIS APPPOOL\appuser(为什么?)
  • [网页内容]
  • 模拟撤消

您似乎缺少表单页面指令中的
Async=“true”
,请尝试以下操作:

<%@ Page Async="true" Language="C#" Async="true"
    AutoEventWireup="true" Inherits="ProxyAddresses" 
    Codebehind="ProxyAddresses.aspx.cs" %>


请发布一些代码。如果你想在页面加载中进行异步计算,你应该声明它为
异步无效
,不要使用RegisterAsyncTask。RegisterAsyncTask用于通知IIS当当前请求结束时不应中止的正在运行的任务非常简单和明显…我虽然尝试了,但没有成功,那么下面的例子是:无论如何,使Page_Load async看起来工作得很完美。
<%@ Page Async="true" Language="C#" Async="true"
    AutoEventWireup="true" Inherits="ProxyAddresses" 
    Codebehind="ProxyAddresses.aspx.cs" %>