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 .
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>: ' + 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 )
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With