TheMook
TheMook

Reputation: 1541

Fairly simple asp.net async operation on page_load is blocking UI

I have a simple page with a list of events. When a button is clicked, it needs to go to the Attendees page and load the people at that event.

What happens at the moment is that after the button is clicked, the events page stays visible until all of the attendees processing is done and finished and then it shows the result. I want it to show first the event name from the first async call then the progress bar I have on the page can show the list of attendees being built. If I load the Attendees page directly with an event ID in the querystring it works as desired with the event name being displayed and the progress bar working.

I don't know how to set this up (Async noob) to get the desired result and would appreciate some pointers please!

In events.aspx.cs button click handler:

Response.Redirect("Attendees.aspx?eventID=" + eventID, false);

Then in Attendees.aspx.cs Page_Load:

    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);
    }

Upvotes: 2

Views: 431

Answers (1)

El Duderino
El Duderino

Reputation: 1392

Take the Attendees loading out of the Page_Load Use an APIController and load the data using jQuery Ajax after the page has loaded.

An API Controller example:

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;
    }
}

The AJAX load

<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>

Upvotes: 2

Related Questions