Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show an informative real time progress data during long server process

I have a so long process may take 1 hour .

This process consists of many steps run from year to year .My main problem is :

How to provide an informative real time progress to the end user during the process not just a dummy loading bar.

            int index = Convert.ToInt32(e.CommandArgument);
            bool done = false;
            int res = -1;
            int fromVal = int.Parse(gv_balance.Rows[index].Cells[0].Text);
            int toVal = int.Parse(gv_balance.Rows[index].Cells[1].Text);
            int finMonth = 1;
            int finYear = 0;
            int EndServ = 0;
            int calcYear = int.Parse(gv_balance.Rows[index].Cells[2].Text);
            int total;
            total = ((toVal - fromVal) + 1);
            string msg = string.Empty;

            int confirm = Balance.GetConfirmState(calcYear);
            if (confirm == 0)
            {
                RadProgressContext progress = RadProgressContext.Current;
                progress.Speed = "N/A";

                finYear = fromVal;

                for (int i = fromVal; i <= toVal; i++)
                {
                    decimal ratio;
                    //Load New Employees
                    if (toVal - fromVal > 0)
                    {
                        ratio = ((decimal)toVal - i) / (toVal - fromVal) * 100;
                    }
                    else
                    {
                        ratio = ((decimal)toVal - i) / 1 * 100;
                    }
                    progress.PrimaryTotal = total;
                    progress.PrimaryValue = total;
                    progress.PrimaryPercent = 100;

                    progress.SecondaryTotal = 100; // total;
                    progress.SecondaryValue = ratio;//i ;
                    progress.SecondaryPercent = ratio; //i;


                    progress.CurrentOperationText = "Step " + i.ToString();
                    if (!Response.IsClientConnected)
                    {
                        //Cancel button was clicked or the browser was closed, so stop processing
                        break;
                    }

                    progress.TimeEstimated = (toVal - i) * 100;
                    //Stall the current thread for 0.1 seconds
                    System.Threading.Thread.Sleep(100);
                    EndServ = i + 1;
                    if (i == fromVal)
                    {   
                        //--->STEP1
                        //Load intial data 
                        int intial = Balance.PrepareIntialData(calcYear);
                        //--->STEP2
                        res = Balance.CalcEndServed(calcYear, EndServ - 1, 6, 30);

                    }
                     //--->STEP3
                    int newEmps = Balance.PrepareNewEmployees(calcYear, i);

                    for (int j = 0; j < 2; j++)
                    {
                        if (j == 0)
                        {
                            finMonth = 7;
                            finYear = i;

                        }
                        else
                        {
                            finMonth = 1;
                            finYear = i + 1;
                        }
                        //--->STEP4
                        int promotion1 = Balance.PreparePromotionFirst(finYear, finMonth, calcYear);
                         //--->STEP5
                        int promotion2 = Balance.PreparePromotionSecond(finYear, finMonth, calcYear);
                         //--->STEP6
                        int appointment1 = Balance.PrepareAppointmentFirst(finYear, finMonth, calcYear);
                         //--->STEP7
                        int appointment2 = Balance.PrepareAppointmentSecond(finYear, finMonth, calcYear);

                        //--->STEP8
                        int bonus = Balance.PrepareBonus(finMonth, finYear, 0, calcYear);

                         //--->STEP9
                        int salary = Balance.PrepareSalary(finYear, finMonth, calcYear);
                     (((CheckBox)gv_balance.Rows[index].Cells[3].FindControl("chk_redirect")).Checked == true)
                        {
                           //--->STEP9
                            int acco = Balance.PrepareFinanceAccount(finYear, finMonth, calcYear);
                        }

                    }


                    //--->STEP10
                    res = Balance.CalcEndServed(calcYear, EndServ, 6, 30);
                    Balance.CalcStudy(calcYear);
                    UpdateProgressContext();
                    if (res < 0)
                    {

                        success_lb.Visible = false;
                        error_lb.Visible = true;
                        error_lb.Text = "ERROR";

                    }
                    else
                    {
                        done = true;
                        success_lb.Visible = true;
                        error_lb.Visible = false;
                        success_lb.Text = "Success";
                    }


                }
            }

I want to show the current step for example : (Promotion 1 ) in ---> 1-2018 and the percentage of the whole process beside the estimated time .

like image 926
Anyname Donotcare Avatar asked May 31 '16 09:05

Anyname Donotcare


2 Answers

To report progress of a very long task using signalR you can do something like this (it's only an example to show how it can work):

Server part

We start by mapping SignalR.

public class Startup
{
   public void Configuration(IAppBuilder app)
   {
       // Any connection or hub wire up and configuration should go here
       app.MapSignalR();
   }
}

We create a hub class (don't forget to install the signalr package):

(If you want to report progress to all connected users or a specific group of users take a look here : http://www.asp.net/signalr/overview/guide-to-the-api/working-with-groups)

In the given example it report progress only to the caller of the Start function.

public class MyHub : Hub
{     
    public void Start(string arg)
    {
        Task.Run(() =>
        {
            AVeryLongTask();
        });
    }

    //simulate a long task
    void AVeryLongTask()
    {
        for (int i = 0; i < 10000; i++)
        {
            Thread.Sleep(100);              
            Clients.Caller.ReportProgress("AVeryLongTask", i * 100 / 10000);
        }
    }
}

Client Part

In the html you must add these references :

<!--Script references. -->
<!--Reference the jQuery library. -->
<script src="Scripts/jquery-1.6.4.min.js"></script>
<!--Reference the SignalR library. -->
<script src="/Scripts/jquery.signalR-2.0.0.js"></script>
<!--Reference the autogenerated SignalR hub script. -->
<script src="/signalr/hubs"></script>

and now the Js part to get the progress from the hub :

 $(function() {
   // Declare a proxy to reference the hub.
   var hub = $.connection.myHub;
   // Create a function that the hub can call to report progress.
   hub.client.reportProgress = function(functionName, progress) {
     $('#progression').append('<li><strong>' + progress + '</strong>:&nbsp;&nbsp;' + functionName + '</li>');
   };
   // Start the connection.
   $.connection.hub.start().done(function() {
     $('#startlongprocess').click(function() {
      //start the long process
       hub.server.start("arg");
       alert("started");
     });
   });
 });

The html container for the progress and the start button :

<div class="container">    
   <input type="button" id="startlongprocess" value="Send" />
   <ul id="progression"></ul>
</div>

If you need more explanations don't hesitate to ask.

( My example is based on this one http://www.asp.net/signalr/overview/getting-started/tutorial-getting-started-with-signalr from signalr team )

like image 120
Quentin Roger Avatar answered Oct 04 '22 05:10

Quentin Roger


You can use web sockets to push progress updates down to the client. SignalR is a dotnet library that wraps websockets and falls back where websockets isn't available. There are comprehensive examples online showing how to implement progress reporting using SignalR so no need to repeat them. Have a look here:

https://github.com/dragouf/SignalR.Progress

or here:

https://www.safaribooksonline.com/blog/2014/02/06/server-side-signalr/

for examples.

like image 21
CamW Avatar answered Oct 04 '22 06:10

CamW