从线程内更新网页 [英] Updating Webpage from Within Thread

查看:58
本文介绍了从线程内更新网页的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个运行冗长程序的网页,除了在页面上显示进度外,所有这些工作都是分开的.

I have a webpage that runs a lengthy procedure, it's all working apart from displaying the progress on the page.

我有以下进度条(引导程序):

I have the following progress bar (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属性:

During the thread, I have the following snippet that adjusts the width property of prgProdFeed:

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属性(按计时器的滴答进行更新).

They both change the width property of the bar which currently sits in an update panel (updated on the tick of a timer).

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

How come my progress bar is not updating on the page? I can see using the inspector that the update panel is refreshing, and in the debugger it's showing the width being correct - just nothing changes visually.

任何帮助将不胜感激.

推荐答案

工作代码如下.

我建议您确保确实更新了更新面板.使用我的代码,您可以对网页进行硬更新(例如F5),您会看到更新的进度.最初,我的刷新更新面板的代码未触发.我当时使用Query来触发对更新面板中刷新"链接按钮的单击,但是我需要更改代码以调用__doPostBack.

I would suggest you make sure your update panel is actually being refreshed. with my code you can do a hard updated of the web page (eg F5) and you'll see updated progress. Initially, my code to refresh the update panel wasn't triggering. I was using Query to trigger a click on the refresh linkbutton in the update panel but I needed to change the code to call the __doPostBack.

我要在您的代码中检查的另一件事是p_objFeedInfo.Progress是双精度型,而p_objFeedInfo.Total是双精度型.您可能会遇到一个问题,其中一个是整数,并且(p_objFeedInfo.Progress / p_objFeedInfo.Total)小于1的双精度结果将被转换为整数,然后将其四舍五入为0,然后再乘以100.

Another thing I would would check in your code is that p_objFeedInfo.Progress is a double and p_objFeedInfo.Total is a double. You could be having an issue where one is an int and the double result from (p_objFeedInfo.Progress / p_objFeedInfo.Total) being less than 1 is converted as in integer rounded down to 0 before being multiplied by 100.

此外,我将width属性组合到一个字符串中,还将prgProdFeed.InnerText设置为该字符串,因此我不必担心检查元素以查看宽度是否在变化.我也在使用Style("Width")设置宽度:

Besides that I am combining the width attribute into a string and also setting prgProdFeed.InnerText to that string so I don't need worry about inspecting an element to see if the width is changing. I am also setting the width use Style("Width"):

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

为了模拟长时间运行的线程,我创建了一个提要类,该提要类采用Total作为构造函数.自创建类以来经过的秒数,它会以两倍的进度返回进度.

To simulate your long running thread I created a feed class that takes Total as a constructor. It returns progress as double based on the number of seconds that have passed since the class was created.

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>

这篇关于从线程内更新网页的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆