So, I have a repeater that displays a list of custom functions on a remote server. The repeater displays as follows.
serverName serviceName serviceStatus Button1 Button2
----------------------------------------------------------
Carolina StatsTracker Running update stop
...
..
.
The serviceStatus is rapped in an update panel inside the repeater
<asp:UpdatePanel ID="statusUpdate" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="false">
<ContentTemplate>
<td><asp:Label ID="RowStatus" Width="100px" Text="Status..." runat="server" /></td>
</ContentTemplate>
</asp:UpdatePanel>
and in the code behind I send commands to the server via servercontroller and attempt to update the serviceStatus real time or at least as close as possible to real time. like this
if (svc.Status != ServiceControllerStatus.Stopped)
{
svc.Stop();
StatusLabel.Text = "Stopping";
statusUPdatePanel.Update();
while (svc.Status != ServiceControllerStatus.Stopped)
{
System.Threading.Thread.Sleep(1000);
svc.Refresh();
}
StatusLabel.Text = svc.Status.ToString();
statusUPdatePanel.Update();
}
System.Threading.Thread.Sleep(1000);
if (svc.Status != ServiceControllerStatus.Running)
{
svc.Start();
StatusLabel.Text = "Starting";
statusUPdatePanel.Update();
while (svc.Status != ServiceControllerStatus.Running)
{
System.Threading.Thread.Sleep(1000);
svc.Refresh();
}
StatusLabel.Text = svc.Status.ToString();
statusUPdatePanel.Update();
}
This issue is that the status doesn't update real time. It only updates to the final value which is either running or error. but never shows the stopping, starting, or stopped as it happens. also on the button click I disable the buttons while the serverController is running, a small user proofing step and which doesn't seem to cause the buttons to become disabled. I've read threw a large number of updatepanel issue post and think it might be a binding issue but i'm am not sure because i have tired the many of those suggested solutions to no avail.
Thanks in advance for any help.
According to your question you would like to refresh your updatePanel twice! That is not possible. The (partial) postback will only occur on your method completing... Furthermore those while (...)
are a bad idea, imo. You could rather use
ServiceController.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 5));
But that would not take care of your problem/question that you would like to see BOTH status (xxxPending and xxx). I think there is only one chance to this - you have to re-ask your server for the current status of a given service. So I created an example in which
Worked fine for me - tested it with my local services.
serviceController_Repeater.aspx
<head runat="server">
<title></title>
<script type="text/javascript" src="js/jquery-1.7.1.js"></script>
<script type="text/javascript">
$(document).ready(function () {
console.log("Add AJAX calls to buttons\n");
$('input[type=button]').click(
function () {
changeStatus($(this).attr("value"), $(this).parents("tr").find("span[id$=lblName]"), $(this).parents("tr").find("span[id$=lblStatus]"));
});
});
function changeStatus(newStatus, displayLabel, statusLabel) {
var displayName = displayLabel.text();
console.log("change status to '" + newStatus + "' for service '" + displayName + "'");
$.ajax({
type: "POST",
url: "serviceController_Repeater.aspx/ChangeStatus",
data: "{ 'newStatus': '" + newStatus + "', 'displayName' : '" + displayName + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
console.log("server says\n\tnew status is now: " + msg.d);
statusLabel.text(msg.d);
if (newStatus != "")
window.setTimeout(function () { changeStatus("", displayLabel, statusLabel) }, 5000);
}
});
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Repeater ID="rptServices" runat="server">
<HeaderTemplate>
<table>
<thead>
<tr>
<th>
Name
</th>
<th>
Status
</th>
<th colspan="4">
</th>
</tr>
</thead>
<tbody>
</HeaderTemplate>
<FooterTemplate>
</tbody></table></FooterTemplate>
<ItemTemplate>
<tr id="1">
<td>
<asp:Label ID="lblName" runat="server" Text='<%# Eval("DisplayName") %>'></asp:Label>
</td>
<td>
<asp:Label ID="lblStatus" runat="server" Text='<%# Eval("Status") %>'></asp:Label>
</td>
<td>
<input type="button" <%# Eval("Status").ToString()=="Stopped" ? "" : "disabled" %> value="Start" />
</td>
<td>
<input type="button" <%# Eval("Status").ToString()=="Running" ? "" : "disabled" %> value="Stop" />
</td>
<td>
<input type="button" <%# Eval("Status").ToString()=="Running" ? "" : "disabled" %> value="Pause" />
</td>
<td>
<input type="button" <%# Eval("Status").ToString()=="Paused" ? "" : "disabled" %> value="Continue" />
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</div>
</form>
</body>
serviceController_Repeater.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
bindServices();
}
private void bindServices()
{
ServiceController[] services = ServiceController.GetServices();
rptServices.DataSource = services;
rptServices.DataBind();
}
[WebMethod]
public static string ChangeStatus(string newStatus, string displayName)//
{
Debug.WriteLine(string.Format("Service {0} new status {1}", displayName, newStatus));
ServiceController sc = new ServiceController(displayName);
switch (newStatus)
{
case "Start":
sc.Start();
// instead of waiting on the SERVER for xxx secondes
// immediately RETURN to CLIENT
//sc.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 15));
break;
case "Stop":
sc.Stop();
break;
case "Pause":
sc.Pause();
break;
case "Continue":
sc.Continue();
break;
default:
break;
}
return sc.Status.ToString();
}