我正在ASP.Net上写一个网页。目前,我有asp:Table
我正在使用它作为处理输出的“日志”。这个想法是用户选择几个文件并单击一个按钮,每个文件都被“处理”,日志显示正在发生的事情。处理以异步方式进行。
以下是相关处理部分:
Protected Sub DoAsyncWork()
Dim count = 0
For Each row As GridViewRow In gvList.Rows
count = count + 1
If CType(row.FindControl("cbImport"), System.Web.UI.WebControls.CheckBox).Checked Then
push_to_log("")
push_to_log("Updating Active Projects +" + HttpUtility.HtmlDecode(row.Cells(1).Text).ToString.Substring(0, 30) + "...")
Dim xp(3) As Object
xp(0) = HttpUtility.HtmlDecode(row.Cells(0).Text)
xp(1) = HttpUtility.HtmlDecode(row.Cells(1).Text)
xp(2) = HttpUtility.HtmlDecode(row.Cells(2).Text)
xp(3) = 0
'oDC.UpdateData("Import_P3e_Project ", xp)
If (xp(3) <> 0) Then
push_to_log("Success: " + xp(3).ToString + " have been updated")
Else
push_to_log("Failure: " + xp(3).ToString + " activities updated")
End If
End If
Next
push_to_log("")
push_to_log("Import Complete!")
End Sub
这就是我调用进程工作者函数的方式:
Protected Sub button_Import(sender As Object, e As EventArgs) Handles btnImport.Click
Dim t As New Thread(New ThreadStart(AddressOf DoAsyncWork))
t.Priority = Threading.ThreadPriority.Normal
t.Start()
push_to_log("Start Import")
End Sub
我将日志附加到日志的方式是动态创建行和单元格,然后将它们添加到我的表格中。这是相关的子程序:
Protected Sub push_to_log(ByVal str As String)
Dim newRow As TableRow = New TableRow
Dim newCell As TableCell = New TableCell
logArrayList.Add(str)
Me.ViewState.Add("arrayListInViewState", logArrayList)
newCell.Text = str
newCell.Style("Color") = "White"
newCell.ID = "cell" + (logArrayList.Count - 1).ToString
newRow.ID = "row" + (logArrayList.Count - 1).ToString
newRow.Cells.Add(newCell)
logTable.Rows.Add(newRow)
HiddenButton_Click(HiddenButton, New EventArgs())
'UpdateLogPanel.Update()
'UpdateLogPanel.Focus()
End Sub
通过使用ViewState存储数据的arraylist并在回发上重新创建日志,我已经正确地保持了日志。我的日志的相关标记如下所示:
<asp:UpdatePanel ID="UpdateLogPanel" UpdateMode="Conditional" runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="HiddenButton" />
</Triggers>
<ContentTemplate>
<div ID="Div1" class="DefinitionPanel" style="text-align:left;height:200px;overflow:hidden;" runat="server">
<span style="display:inline-block; width:100px;"></span>
<div class="scrollingtable">
<div>
<div id="viewContainer">
<asp:table id="logTable" runat="server" enableviewstate="false">
</asp:table>
</div>
</div>
</div>
</div>
<asp:Button ID="HiddenButton" runat="server" style="display:none;" />
</ContentTemplate>
</asp:UpdatePanel>
每次向其发布消息时,我都会尝试更新asp:Table
。我认为启用部分回发并使用UpdatePanel
将是正确的解决方案,但在整个过程完成之前,我的日志仍然不会输出任何内容。
在我向asp:Table
/ log添加消息后,我尝试调用
UpdateLogPanel.Update()
似乎没有什么区别。最后,我尝试添加asp:AsyncPostBackTrigger
和隐藏按钮,希望它可以解决问题,但似乎没有。以下是hiddenButton
事件的样子:
Protected Sub HiddenButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles HiddenButton.Click
UpdateLogPanel.Visible = True
End Sub
当我向其添加消息时,如何使我的日志重新呈现自己的指导将受到高度重视。
答案 0 :(得分:0)
我选择使用池而不是异步方法来实现。
我仍然使用asp:UpdatePanel。我现在使用的是gridview和一个计时器,而不是UpdatePanel中的表。当计时器触发时,我重新绑定gridview,从而显示任何新内容
使这项工作的关键组成部分:
使用父更新面板和母版页来解决问题:
Private Sub Page_Init(sender As Object, e As System.EventArgs) Handles Me.Init
'set reference to master site page
mstr = CType(Master, Site)
'setup partial rendering so Log can update asynchronously
scriptManager = CType(mstr.FindControl("ScriptManager1"), ScriptManager)
scriptManager.EnablePartialRendering = True
scriptManager.AsyncPostBackTimeout = 28800
CType(mstr.FindControl("UpdatePanel1"), UpdatePanel).UpdateMode = UpdatePanelUpdateMode.Conditional
CType(mstr.FindControl("UpdatePanel1"), UpdatePanel).ChildrenAsTriggers = False
End Sub
UpdatePanel的标记看起来像
<asp:UpdatePanel ID="UpdateLogPanel" UpdateMode="Conditional"
RenderMode="Inline" ChildrenAsTriggers="false" runat="server">
<ContentTemplate>
<%--The Gridview and other Hidden Fields--%>
<asp:Timer ID="myTimer" OnTick="timer_tick" runat="server" Interval="1000" Enabled="false"/>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="myTimer" EventName="Tick" />
</Triggers>
</asp:UpdatePanel>
只需通过设置即可触发日志记录机制 myTimer.Enabled = True
timer_tick事件看起来像
Public Sub timer_tick(ByVal sender As Object, ByVal e As EventArgs)
generate_log()
//other logging logic (increment counters, "timeout" mechanism)
UpdateLogPanel.Update()
End Sub