1

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

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 运行时禁用按钮,这是一个小的用户校对步骤,这似乎不会导致按钮被禁用。我已经阅读了大量的更新面板问题帖子,并认为这可能是一个绑定问题,但我不确定,因为我已经厌倦了许多建议的解决方案,但无济于事。
提前感谢您的帮助。

4

1 回答 1

1

根据您的问题,您想刷新您的 updatePanel两次!这是不可能的。(部分)回发只会在您的方法完成时发生......此外,这些while (...)都是一个坏主意,imo。你宁愿使用_

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

但这不会解决您希望同时查看状态(xxxPending 和 xxx)的问题/问题。我认为只有一次机会 - 您必须重新向服务器询问给定服务的当前状态。所以我创建了一个例子

  1. 我使用JQUery AJAX 调用更改服务的状态
  2. 成功后,我立即获取服务器响应并将其显示在客户端上(通常为xxxPending
  3. 在客户端等待5 秒,然后重新向服务器询问此服务的当前状态

对我来说效果很好 - 用我的本地服务对其进行了测试。

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();
}
于 2012-09-05T19:52:41.417 回答