从内部线程更新网页

时间:2017-06-29 11:27:32

标签: asp.net vb.net multithreading twitter-bootstrap

我有一个运行冗长程序的网页,除了在页面上显示进度外,它们都在工作。

我有以下进度条(Bootstrap):

<div class="col-md-8">
  <label for="product-feed-progress">Progress</label>
    <div class="progress">
     <div class="progress-bar" role="progressbar" runat="server" id="prgProdFeed" style="min-width: 0em; width: 0%;">
                                    0%
     </div>
  </div>
</div>

在线程中,我有以下代码片段来调整prgProdFeed的width属性:

prgProdFeed.Attributes.Add("style", "width:" & ((p_objFeedInfo.Progress / p_objFeedInfo.Total) * 100).ToString() + "%")

我也尝试过:

prgProdFeed.Style.Item("width") = ((p_objFeedInfo.Progress / p_objFeedInfo.Total) * 100).ToString() + "%"

它们都会更改当前位于更新面板中的栏的width属性(在计时器的刻度上更新)。

为什么我的进度条没有在页面上更新?我可以看到使用检查器更新面板是否刷新,并且在调试器中它显示宽度正确 - 只是没有任何视觉上的变化。

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:4)

工作代码如下。

我建议您确保更新面板实际上已刷新。使用我的代码,您可以对网页进行硬更新(例如F5),您将看到更新的进度。最初,我的代码刷新更新面板没有触发。我使用Query来触发更新面板中刷新链接按钮的单击,但我需要更改代码以调用__doPostBack。

我会在您的代码中检查的另一件事是p_objFeedInfo.Progress是双精度而p_objFeedInfo.Total是双精度。你可能会遇到一个问题,其中一个是int,而(p_objFeedInfo.Progress / p_objFeedInfo.Total)小于1的双重结果被转换为整数,在乘以100之前向下舍入为0.

除此之外,我将width属性组合成一个字符串,并将prgProdFeed.InnerText设置为该字符串,因此我不需要担心检查元素以查看宽度是否在变化。我也设置宽度使用样式(“宽度”):

Dim progressAttribute As String = progress & "%"
Me.prgProdFeed.Style("Width") = progressAttribute
Me.prgProdFeed.InnerText = progressAttribute

为了模拟长时间运行的线程,我创建了一个以Total为构造函数的feed类。它根据自创建类以来经过的秒数返回进度为double。

Public Class ProgressBar
    Inherits System.Web.UI.Page

    Public Class FeedInfo
        Public ReadOnly Property Progress As Double
            Get
                Return Math.Min(Now.Subtract(Created).TotalSeconds, Total)
            End Get
        End Property

        Public Total As Double
        Public Created As DateTime
        Public Sub New(Total)
            Me.Total = Total
            Created = Now
        End Sub
    End Class
    Private Property info As FeedInfo
        Get
            If (Not Session("info") Is Nothing) Then
                Return Session("info")
            End If
            Return Nothing
        End Get
        Set(value As FeedInfo)
            Session("info") = value
        End Set
    End Property

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim progress As Integer = 0
        If (Not info Is Nothing) Then
            Dim tracker As FeedInfo = info
            Dim trackerProgress As Double = tracker.Progress
            Dim trackerTotal As Double = tracker.Total
            progress = ((trackerProgress / trackerTotal) * 100)
        End If
        Dim progressAttribute As String = progress & "%"
        Me.prgProdFeed.Style("Width") = progressAttribute
        Me.prgProdFeed.InnerText = progressAttribute

    End Sub

    Private Sub runProc_Click(sender As Object, e As EventArgs) Handles runProc.Click
        info = New FeedInfo(600)
    End Sub
End Class
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="ProgressBar.aspx.vb" Inherits="EFWCFVB.ProgressBar" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Long Running Task Progress Bar</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <script>
        var timerId = 0;
        function trackProgress() {
            if (timerId && timerId != 0)
                return;
            timerId = window.setInterval(refreshProgress, 2000);
        }
        function refreshProgress() {
            if ($('.progress-bar').html() == "100%") {
                window.clearInterval(timerId); return;
            }
            //  $('#btnRefresh').click(); does not work
            // var href = $('#btnRefresh').attr("href").split[0]; //"javascript:__doPostBack('btnRefresh','')"
            __doPostBack('btnRefresh', '');

        }
        $(document).ready(function () {
            trackProgress();
            $('#runProc').click(function () { trackProgress();})
        })
    </script>
</head>
<body>
    <form id="form1" runat="server">
        <h2>Long Running Task Progress Bar</h2>
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <div class="form-group">
                    <div class="col-md-8">

                        <label for="product-feed-progress">Progress</label>
                        <div class="progress">
                            <div class="progress-bar" role="progressbar" runat="server" id="prgProdFeed" style="min-width: 0em; width: 0%;">
                                0%
                            </div>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-md-8">
                        <asp:Button ID="runProc" runat="server" Text="Run" />
                        <asp:LinkButton ID="btnRefresh" runat="server" Text="Refresh Panel">

                        </asp:LinkButton>
                    </div>
                </div>
            </ContentTemplate>

        </asp:UpdatePanel>


    </form>
</body>
</html>

答案 1 :(得分:-1)

&#34;宽度&#34;不是条形图对象的正确属性。通常,width表示整个对象的宽度。

您需要寻找&#34; &#34;属性而不是&#34;宽度&#34;