C# 页面加载上相当简单的asp.net异步操作阻塞了UI

C# 页面加载上相当简单的asp.net异步操作阻塞了UI,c#,asp.net,async-await,C#,Asp.net,Async Await,我有一个简单的页面,上面有一个事件列表。单击按钮时,需要转到“与会者”页面并加载该活动的参与者 此时发生的情况是,单击按钮后,“事件”页面保持可见,直到所有与会者处理完毕并完成,然后显示结果。我希望它首先显示第一次异步调用中的事件名称,然后页面上的进度条可以显示正在生成的与会者列表。如果我在querystring中直接加载带有事件ID的Attenders页面,它将根据需要工作,并显示事件名称和进度条 我不知道如何设置(异步noob)以获得所需的结果,请提供一些提示 在events.aspx.cs

我有一个简单的页面,上面有一个事件列表。单击按钮时,需要转到“与会者”页面并加载该活动的参与者

此时发生的情况是,单击按钮后,“事件”页面保持可见,直到所有与会者处理完毕并完成,然后显示结果。我希望它首先显示第一次异步调用中的事件名称,然后页面上的进度条可以显示正在生成的与会者列表。如果我在querystring中直接加载带有事件ID的Attenders页面,它将根据需要工作,并显示事件名称和进度条

我不知道如何设置(异步noob)以获得所需的结果,请提供一些提示

在events.aspx.cs按钮中,单击处理程序:

Response.Redirect("Attendees.aspx?eventID=" + eventID, false);
然后在Attendes.aspx.cs页面中加载:

    protected void Page_Load(object sender, EventArgs e)
    {
        processEvent(); 
        //I've tried this with .Wait() at the end too
    }

    private async Task<bool> processEvent()
    {
        try
        {
            EFEventDetails efEvent = await getEventByIdAsync();
            if (efEvent.responseCode != 200) //only 200 is a valid response code for a found event
            {
                pnl_loadingError.Visible = true;
                pnl_attendees.Visible = false;
            }
            else
            {
                //valid event - carry on. Display event name on page.
                lbl_EventHeader.Text = efEvent.data.eventID.ToString() + " - " + efEvent.data.eventName;

                //Now get list of attendees
                List<vmAttendees> res = await getAttendeesAsync();
                if (res.Count > 0)
                {
                    pnl_AttendeeList.Visible = true;
                    rpt_AttendeeList.DataSource = res;
                    rpt_AttendeeList.DataBind();
                }

            }

        }
        catch (Exception ex)
        {

            lbl_Result.Text = ex.Message;
            lbl_Result.ForeColor = System.Drawing.Color.Red;
            pnl_processResult.Visible = true;
        }

        return true;
    }

    protected async Task<EFEventDetails> getEventByIdAsync()
    {
        var eventsForceService = new EventsForceService(_eventsForceRepo);
        return await eventsForceService.getEventByIdAsync(_eventID);
    }

    protected async Task<List<vmAttendees>> getAttendeesAsync()
    {
        var eventsForceService = new EventsForceService(_eventsForceRepo);
        return await eventsForceService.GetAttendeesByEventIDAsync(_eventID);
    }
受保护的无效页面加载(对象发送方,事件参数e)
{
processEvent();
//我也试过了。等一下()结尾
}
私有异步任务processEvent()
{
尝试
{
EFEventDetails efEvent=await getEventByIdAsync();
if(efEvent.responseCode!=200)//对于找到的事件,只有200是有效的响应代码
{
pnl_loadingError.Visible=true;
pnl_attendes.Visible=false;
}
其他的
{
//有效事件-继续。在第页显示事件名称。
lbl_EventHeader.Text=efEvent.data.eventID.ToString()+“-”+efEvent.data.eventName;
//现在获取与会者名单
List res=await getAttendeesAsync();
如果(分辨率计数>0)
{
pnl_attendelist.Visible=true;
rpt_attendelist.DataSource=res;
rpt_attendelist.DataBind();
}
}
}
捕获(例外情况除外)
{
lbl_Result.Text=消息外;
lbl_Result.ForeColor=System.Drawing.Color.Red;
pnl_processResult.Visible=true;
}
返回true;
}
受保护的异步任务getEventByIdAsync()
{
var eventsForceService=新的eventsForceService(_eventsForceRepo);
return wait events forceservice.getEventByIdAsync(_eventID);
}
受保护的异步任务getAttendeesAsync()
{
var eventsForceService=新的eventsForceService(_eventsForceRepo);
return wait events forceservice.getAttendesByventidAsync(\u eventID);
}

将与会者从
页面中取出\u Load
使用APIController,并在页面加载后使用jQuery Ajax加载数据

API控制器示例:

public class AttendeesController : ApiController
{
    Attendee[] attendees = new Attendee[] 
    { 
        new Attendee { Id = 1, Name = "Mike" }, 
        new Attendee { Id = 2, Name = "Steve" }, 
        new Attendee{ Id = 3, Name = "Diane" } 
    };

    public IEnumerable<Attendee> GetAllAttendees()
    {
        // This is using a premade list of Attendees 
        // but you would get them here and return them

        // Will convert to JSON automatically
        return attendees;
    }
}
公共类与会者控制器:ApiController
{
与会者[]与会者=新与会者[]
{ 
新与会者{Id=1,Name=“Mike”},
新与会者{Id=2,Name=“Steve”},
新与会者{Id=3,Name=“Diane”}
};
公共IEnumerable GetAllAttendees()
{
//这是使用预先制作的与会者列表
//但是你可以把它们拿到这里,然后还回去
//将自动转换为JSON
返回与会者;
}
}
AJAX负载

<script type="text/javascript">
    $.get( "Attendees/GetAllAttendees", function( data ) {
        // Load the data into the page after it returns
        $( ".result" ).html( data );
        alert( "Load was performed." );
    });
</script>

$.get(“与会者/GetAllattendes”,函数(数据){
//返回后将数据加载到页面中
$(“.result”).html(数据);
警报(“已执行加载”);
});

如果需要,我很乐意使用ajax调用,但在这种情况下,如果可能,我会尽量避免使用ajax调用。这真的是实现我目标的唯一途径吗?仅仅用C代码是没有办法做到这一点的吗?如果你想要一个在加载时更新的进度条,它需要某种类型的AJAX。页面加载是在服务器端完成的。页面在完成之前不会加载。因此,如果有数据调用,它将始终等待它。要在不等待调用的情况下加载页面,需要将页面返回到客户端,然后使用AJAX加载数据。感谢评论中的其他有用的链接,它们是有用的阅读。这种方法的缺点是,我将/将不得不重新编码asp.net代码中已经存在的逻辑,该代码将返回的数据绑定到中继器,并在绑定时格式化行颜色和属性。这并不能解决如何获取工作进度条的问题,但是,如果您只想等到页面完全加载后再显示任何内容,那么您应该在
Page\u Load
(您需要调用
RegisterAsyncTask(processEvent());
,并确保您的aspx页面的
页面
元素中包含
Async=“true”
)来查看正确的操作。谢谢Scott。如果你查看我的原始帖子,你可以看到我已经有了进度条的东西,如果我直接加载页面的话,效果很好。我正在使用信号器和事件处理程序。我现在正在读你发的那篇文章。谢谢