2

this method - doDayBegin(item.BranchId) is taking long time to execute. so i am using Parallel.ForEach to execute it parallel. my problem is now i want to show the progress on webpage so user will come to know the progress.
i am not expert in threading. so give my suggestion what can i do? how can i accomplished this. i realy dont have any idea.

   public ActionResult Edit([DataSourceRequest] DataSourceRequest request)
        {
            try
            {

                JavaScriptSerializer js = new JavaScriptSerializer();
                List<DB0010020Vm> _listDB0010020Vm = new List<DB0010020Vm>();

                string dataDB0010020vm = Request.Form["griddetailsvm"];
                if (!string.IsNullOrEmpty(dataDB0010020vm))
                {
                    _listDB0010020Vm = js.Deserialize<List<DB0010020Vm>>(dataDB0010020vm).
                    Where(d => d.IsValid == "YES").ToList();
                }
                DateTime start = DateTime.UtcNow;
                var context = System.Web.HttpContext.Current;


                Parallel.ForEach(_listDB0010020Vm, item =>
                {
                    doDayBegin(item.BranchId, context);
                });

                DateTime end = DateTime.UtcNow;
                TimeSpan duration = end - start;
                return Json(new
                {
                    success = true,
                    message = "Day Begin Process Completed Successfully!" + duration
                });
            }
            catch (Exception e)
            {
                return Json(new
                {
                    success = false,
                    message = e.Message
                });

            }
        }
dvirus
  • 206
  • 3
  • 17

1 Answers1

8

After the doDayBegin function call, you could add a few lines that increment a counter in a thread-safe manner. The counter would thus represent the number of iterations that have completed. To update a progress bar, adding a function which sets the object to the new value works well.

doProcessing(){
    UInt16 count= 0;
    Object countLock= new Object();

    Parallel.ForEach(_listDB0010020Vm, item =>
    {
        doDayBegin(item.BranchId, context);
        lock (countLock) { updateProgressBar(++count); }
    });
}

updateProgressBar(UInt16 progress){
    textBox1.Text = progress;
}

'count' will iterate from 0 through however long your list is.

There's a helpful blog post on reporting progress at:
http://blog.stephencleary.com/2012/02/reporting-progress-from-async-tasks.html

  • how to pass this to view continuously. – dvirus Nov 04 '14 at 10:39
  • Locking for incrementing an integer will lead to unnecessary contention, that's what atomic instructions are there for. – Voo Nov 04 '14 at 10:51
  • Well, you have how many days have been processed in the 'count' variable, all you need is the total number of days to be processed - I'd assume you can pull that from the '_listDB0010020Vm' variable by using it's .Count property (http://msdn.microsoft.com/en-us/library/27b47ht3%28v=vs.90%29.aspx) – Connor McGuinness Nov 04 '14 at 12:51
  • I think the trouble is that you need a mechanism to notify the UI that the progress has changed. Typically you might use an event for this, but that gets tricky in the Parallel context. You could use a timer to constantly update the UI, but that's ugly too. – Kohanz Sep 25 '15 at 15:07