Click here to Skip to main content
15,881,938 members
Please Sign up or sign in to vote.
5.00/5 (2 votes)
Quick description
I have a simple ASP.NET MVC application with two views. One of those views has a button which uses an Ajax form submit to call a method on the controller.
That method on the controller first makes an asynchronous method call on the model instance which executes a long running process. The controller method then makes another asynchronous method call to another method on that same controller. That method contains a polling mechanism to determine when the first asynchronous long running method call has completed.
Since both method calls (on the model and on the same controller) are asynchronous, the view is returned to the user to say that the process has begun.
When the long running process on the model completes, the asynchronous method on the controller picks-up on this, updates the model to say that the process has completed and then returns the view to the user again.

Current problem, if you haven't already guessed
From the user's perspective, they click the button and get a response to say the process has begun, but that's all that happens. When the process completes and the view is returned to the user a second time, the view does not get refreshed.

Original Problem
Previously, there was no a-synchronicity in this application, but because these are long running processes the users never knew what the progress was. And there was network issues or timeouts, the page would never refresh at all, even when the long running process completed. Currently I have resolved those issues by implementing async await but the user still does not know what the status of the long running process is.

Sample Code
In controller's action method the Import method calls model's the long running process.
Then the controller's asynchronous AsynchPollForImportComplete method is called.
C#
Import(model);
AsyncImportPollDelegate asynchImportPollDelegate = new AsyncImportPollDelegate(AsynchPollForImportComplete);
IAsyncResult asynchPollResult = asynchImportPollDelegate.BeginInvoke(asynchResult, model, null, null);


Here is the AsynchPollForImportComplete method in the controller. I have tried to return the view in various ways to no avail.

C#
private ActionResult AsynchPollForImportComplete(IAsyncResult asynchResult, IHomeModel model)
{

    int x = 1;
    // Poll while waiting a bit.
    while (asynchResult.IsCompleted == false)
    {
        x++;
        Thread.Sleep(1000);        
        if (x == 4) x = 1;
    }
    model.ImportSuccessMsg = "The files have imported successfully.";
    TempData["Model"] = model;

    return Redirect("Index");
    //return RedirectToAction("Index", model);
    //return Redirect(Request.UrlReferrer.ToString());
    //return View("Index", model);
}


Finally
I don't have much ASP.MVC experience, as you could probably already tell :) so I don't know what is the best way to achieve this. I am hoping for the easiest way of getting this to work the way it is but understand that is maybe not possible.
I have read up on SignalR, which looks really good, but it would require a substantial reworking on of the project which I would like to avoid.

Any help is appreciated
Thanks and Regards

Edit - Found my solution
I added this to Index.cshtml.
XML
<script type="text/javascript">
    setInterval(function(){getdata()}, 5000);
    function getdata()
    {
        $.get("/Home/GetImportResult", function(data) {
            document.getElementById("lblImportSuccessMsg").innerHTML = data
        });
    }
</script>


And put the following into the controller. The AsynchPollForImportComplete method in the controller does not need to return anything.
C#
public string GetImportResult()
{
    if (model != null)
        return model.ImportSuccessMsg;
    else return null;
}
Posted
Updated 13-Mar-13 10:45am
v3
Comments
Nelek 15-Mar-13 5:40am    
"Nice question". Not so usual to see.

You can post the solution you found as an Answer to the question and then accept it. This is sometimes abused, but in your case I find it the correct way.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900