使用ServerController和更新面板更新无法正常工作

时间:2012-09-05 13:11:30

标签: c# ajax updatepanel repeater servercontrols

所以,我有一个转发器,它在远程服务器上显示自定义函数列表。转发器显示如下。

serverName   serviceName    serviceStatus   Button1 Button2
----------------------------------------------------------
 Carolina    StatsTracker      Running       update  stop
 ...
 ..
 .

serviceStatus在转发器内的更新面板中敲击

<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>

在后面的代码中我通过servercontroller向服务器发送命令,并尝试实时更新serviceStatus或至少尽可能接近实时。像这样

                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();

                } 

此问题是状态不会实时更新。它只更新为运行或错误的最终值。但从未显示停止,启动或停止发生的情况。同样在按钮上单击我在serverController运行时禁用按钮,这是一个小的用户校对步骤,并且似乎不会导致按钮被禁用。我读了大量的updatepanel问题帖子并认为这可能是一个有约束力的问题,但我不确定,因为我已经厌倦了许多建议的解决方案无济于事。
在此先感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

根据您的问题,您希望刷新您的updatePanel 两次!这是不可能的。 (部分)回发只会在你的方法完成时发生......而且那些while (...)是个坏主意,imo。您可以而非使用

ServiceController.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 5));

但是你不希望看到你想要看到两个状态(xxxPending和xxx)的问题/问题。我认为这只有一次机会 - 您必须重新询问服务器以获取给定服务的当前状态。所以我创建了一个

的例子
  1. 我使用 JQUery AJAX调用更改服务状态
  2. 成功立即服务器响应在客户端上显示(通常 xxxPending
  3. 在客户端上等待 5秒重新询问服务器以获取此服务的当前状态
  4. 为我工作得很好 - 用我当地的服务进行测试。

    <强> 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();
    }