从线程内更新网页 [英] Updating Webpage from Within Thread
问题描述
我有一个运行冗长程序的网页,除了在页面上显示进度外,所有这些工作都是分开的.
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屋!