Question

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.

Was it helpful?

Solution

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

  1. I use an JQUery AJAX call to change the status of a service
  2. on success I take the immediate server response and show it on the client (usually xxxPending)
  3. wait for 5 secs on the client and re-ask the server for the current status of this service

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();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top