【问题标题】:Weird behavior of UpdatePanel with Session vs. ViewStateUpdatePanel 与 Session 与 ViewState 的奇怪行为
【发布时间】:2017-04-27 18:21:19
【问题描述】:

早上好,

这更像是一个 WTF 类型的问题,而不是其他任何问题。

我的应用程序正在使用 ViewState。我在我的应用上放置了一个 UpdatePanel,仅用于测试目的。它所做的只是每秒访问我的日志表并生成一个实时日志控制台,让我查看应用程序如何处理事情。

今天早上我决定将ViewState 改用Session。现在我的 UpdatePanel 不再同步运行并“暂停”,直到更新 UpdatePanel/Console 的操作完成。

切换回 ViewState 让事情正常运行...

另外,我的 UpdatePanel 正在调用的函数与 ViewState 或 SessionState 无关,也没有调用...

我已经能够在小型测试样本中重现此行为:

TestUpdatePanelWithSession.Master

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="TestUpdatePanelWithSession.master.cs" Inherits="Tester2._0.TestUpdatePanelWithSession1" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <asp:ContentPlaceHolder ID="head" runat="server">
    </asp:ContentPlaceHolder>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
        <asp:Timer ID="Timer1" runat="server" Enabled="True" Interval="1000"></asp:Timer>
        <div>
            <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
            </asp:ContentPlaceHolder>
        </div>
        <asp:UpdatePanel ID="UpdatePanel1"
            UpdateMode="Always"
            runat="server">
            <Triggers>
                <asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
            </Triggers>
            <ContentTemplate>

                <%= System.DateTime.Now.ToString("mm:ss") %>

                    </div>
            </ContentTemplate>
        </asp:UpdatePanel>
    </form>
</body>
</html>

TestUpdatePanelWithSession.aspx

<%@ Page Title="" Language="C#" MasterPageFile="~/TestUpdatePanelWithSession.Master" AutoEventWireup="true" CodeBehind="TestUpdatePanelWithSession.aspx.cs" Inherits="Tester2._0.TestUpdatePanelWithSession" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    <asp:Label ID="lblTest" runat="server" Text="Label"></asp:Label>
    <asp:Button ID="btnStartTest" runat="server" Text="Test" OnClick="btnStartTest_Click" />
</asp:Content>

TestUpdatePanelWithSession.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Tester2._0
{
    public partial class TestUpdatePanelWithSession : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                Session["SomeIndex"] = 50000;
            }
        }

        protected void btnStartTest_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < 1000000; i++)
            {
                System.Threading.Thread.Sleep(500);
                Session["SomeOtherIndex"] = i;

                lblTest.Text = ((int)Session["SomeIndex"] + (int)Session["SomeOtherIndex"]).ToString();
            }
        }
    }
}

如果您将所有 Session 更改为 ViewState,上述代码可以正常工作。到底是怎么回事??

提前感谢您的课程...

【问题讨论】:

  • 没有代码我们无能为力。
  • 我真的不确定要在这里显示什么代码。它贯穿我的整个应用程序。当我从使用 ViewState 切换到使用 Sessions 来存储各种对象时,这种行为就开始了。当这个开关完成时,肯定有一些解释来解释 UpdatePanel 的行为(不看代码)?或者也许它应该与 Session 一起正常工作,就像它与 ViewState 一样,在这种情况下,我将尝试识别导致 UpdatePanel 执行此操作的区域。
  • 我可以向您保证,在 UpdatePanel 中使用 Session 不会改变它的行为,我在使用 ASP .net 时一直在广泛使用它。
  • @Gusman,我已经能够在上面添加的测试样本中重现该行为。
  • ContentPlaceholder 在 UpdatePanel 之外...

标签: c# session viewstate


【解决方案1】:

在测试示例后,很明显问题来自会话的读写锁。

从 Page_Load 中删除会话使用可以避免这种行为,但这有点奇怪,因为当更新面板调用页面时代码没有被命中。即使将代码移动到其他函数、在另一个线程上调用它或使用任务也不会阻止这种行为。

似乎 ASP .net 正在分析代码,当有代码使用会话时,即使它没有执行,它也会阻止会话,从而阻止回调的正常执行。在控制事件上只保留会话操作似乎可以正常工作。

我测试过的唯一解决方案是删除 Page_Load 会话操作,在某些情况下这是不可避免的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-19
    • 2021-10-30
    • 2022-01-20
    • 2018-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多