3

I am learning async await and implementing in my old asp.net. I am using c# 4.6.

Now the page is always running synchronously after adding async-await. It's waiting for the api to send back result and then shows the message on screen.

What I am looking for is that the page kicks off a thread and be responsive(I can do other bits on it). When it's completed, it shows the result.

Below is my button click, HTTP call (which will initiate the async req) and API method .

I have

  1. Followed the examples https://msdn.microsoft.com/en-us/library/hh191443.aspx
  2. Looked for solution on StackOverflow and other forums. I believe I am doing it the same way (which of course I am not :( ).

Added Async="true" on aspx page.

Button Click

protected async void btnCopy_Click(object sender, EventArgs e)
    {
        await RunAsync(Guid.Parse(SourceBusinessID), Guid.Parse(DestinationBusinessID), false);

        if (lblError.Text == "")
        {
            lblError.Text = "Copy Completed!";
        }            
    }

public async Task RunAsync( Guid SourceBusinessID, Guid DestinationBusinessID,bool copyAdviser)
    {
        using (var client = new HttpClient())
        {
            var request = new HttpRequestMessage()
            {
                RequestUri = new Uri("http://localhost:52140/api/DummyAccounts/"),
                Method = HttpMethod.Get,
            };
            request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain"));

            client.Timeout = TimeSpan.FromSeconds(500);

            var response = await client.SendAsync(request);

            if (!response.IsSuccessStatusCode)
            {                    
                lblError.Text = response.StatusCode.ToString();
            }
        }
    }

API

public IHttpActionResult Get(Guid sourceBusinessID, Guid destinationBusinessID,bool copyAdviser = true)
    {
        try
        {
            CopyHelper.SourceBusinessID = sourceBusinessID;
            CopyHelper.DestinationBusinessID = destinationBusinessID;
            CopyHelper.CopyAdviser = copyAdviser;

            logger.Info("Copy buisness started:" + DateTime.Now);

            bool status = CopyBusinessService.CopyBusiness(CopyHelper.SourceBusinessID, CopyHelper.DestinationBusinessID, CopyHelper.CopyAdviser);
            if (status)
            {
                logger.Info("Copy business finished:" + DateTime.Now);

                return Ok(true);
            }
            else
            {
                logger.Info("Copy business failed:" + DateTime.Now);

                return Ok(false);
            }
        }
        catch (Exception ex)
        {
            return InternalServerError(ex);
        }

    }

Any help will be much appreciated.

2
  • 4
    I think you may be a little confused. I'd recommend reading Async doesn't change the HTTP protocol by Stephen Cleary. Commented Apr 19, 2016 at 7:09
  • Thanks @Damien_The_Unbeliever it was really helpful. Commented Apr 20, 2016 at 0:03

1 Answer 1

9

Async in a WebForms application doesn't make your form behave like a client side application that sits and in an event loop and waits for events to happen. It's still a server rendered page that responds to single, transactional HTTP requests triggered by a button click or change event, with a single server rendered HTML response by the WebForm. Once rendered the page is done. There's no 'event loop' that waits for the next click.

Async in a WebForms/ASP.NET app simply allows you to offload some processing from the main thread, but it doesn't not change the behavior of the UI on the page. Think of async as a way to either run multiple operations simultaneously, or to release the main processing thread while a longer running IO operation runs in the background, then returns before the final page is rendered.

But it doesn't do anything for the way the page will actually render into the browser or behave - a WebForms page is still a purely server rendered page that handles events via HTTP postbacks. As far as the browser is concerned it's a transactional request: You click a button and the page re-renders regardless of whether you use Async on the backend or not.

The way to solve your problem is to use a client side JS framework to manage your application's async flow and make asynch HTTP calls to the server. That will give you the behavior you are looking for, where a long request that can run 'in the background' while letting your client side application continue with other operations. The server then eventually calls you back when the operation is complete and you can then use the response data to display the results or notify the user.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank @Rick I will probably move to js frameworks. Though one interesting thing, if I remove await from await RunAsync(Guid.Parse(SourceBusinessID), Guid.Parse(DestinationBusinessID), false); in my Button Click event then the method runs sync and I can do other stuff while the api is working on the background. But when the API finishes the job, it somehow kill the main worker process. I then have to rebuild my solution to start again. I don't understand why did my main worker process die?
You can't remove the AWAIT on an ASYNC operation. It'll still run but run asynchronously and not wait. Your request will finish and when the Aysnc operation finishes doing whatever it was doing it'll find the page is no longer there and then - BOOM. Again you need to do a bit of reading of how ASYNC on the server works - you are confusing client side and server side async functionality and until you figure that out you're going to have problems.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.