Search code examples
asp.net-mvc-3c#-4.0asynccontroller

AsyncController callback not being invoked, how to invoke it?


Hello i'm trying to implement an AsynController,

here is my code:

[NoCache]
public class GraphController : BaseAsyncController
{
    private readonly IReportsRepository _reportsRepository;
    private readonly ISqlQueryRepository _sqlQueryRepository;

    //Background worker
    private readonly BackgroundWorker _worker = new BackgroundWorker();

    public GraphController(ISqlQueryRepository sqlQueryRepository, IReportsRepository reportsRepository)
    {
        _sqlQueryRepository = sqlQueryRepository;
        _reportsRepository = reportsRepository;
    }

    public void Index()
    {
        AsyncManager.OutstandingOperations.Increment();

        _worker.DoWork += (sender, args) =>
        {
            AsyncManager.Parameters["message"] = "hello world";
            Thread.Sleep(3000);
        };

        _worker.RunWorkerCompleted += (sender, args) => AsyncManager.OutstandingOperations.Decrement();
        //run the worker
        _worker.RunWorkerAsync();
    }

    public ActionResult IndexCompleted(string message) //callback not being invoked
    {
        ViewData["message"] = message;
        return View();
    }
}

The question is why the completed callback is not being invoked?

Thanks in advance.


Solution

  • The name of your action is wrong. It should not be Index. It should be IndexAsync. Take a look at the following article which illustrates the usage of asynchronous controllers in ASP.NET MVC.

    Note that BackgroundWorker is a Windows Form component. Don't use WinForms components in ASP.NET applications. They are not designed to be used in server applications. I'd recommend you TPL.

    So:

    [NoCache]
    public class GraphController : BaseAsyncController
    {
        private readonly IReportsRepository _reportsRepository;
        private readonly ISqlQueryRepository _sqlQueryRepository;
    
        public GraphController(ISqlQueryRepository sqlQueryRepository, IReportsRepository reportsRepository)
        {
            _sqlQueryRepository = sqlQueryRepository;
            _reportsRepository = reportsRepository;
        }
    
        public void IndexAsync()
        {
            AsyncManager.OutstandingOperations.Increment();
            Task.Factory.StartNew(() => 
            {
                // do the work
                Thread.Sleep(3000);
    
                // the work is finished => pass the results and decrement
                AsyncManager.Parameters["message"] = "hello world";
                AsyncManager.OutstandingOperations.Decrement();
            });
        }
    
        public ActionResult IndexCompleted(string message)
        {
            ViewData["message"] = message;
            return View();
        }
    }