如何创建只要用户在页面上就只 运行 一次的逻辑(即用户不会转到不同的页面并返回)

How to create logic that will run ONLY once as long as the user is on the page (ie user does not go to a different page and come back)

您好,我遇到了这个问题,每当我的 AJAX 计时器被触发时,我的 Page_Load 函数中的逻辑就会被调用。幸运的是,我使用更新面板来区分异步回发,它现在捕获来自 AJAX 计时器的调用。然而,每隔一段时间(我会说可能每 15 秒左右),我在 Page_Load 运行 中的逻辑再次通过(我不确定这是否是 AJAX 未被捕获的回调或其他东西)。当最初加载页面时,我该如何做到逻辑 运行 一次且仅一次?请注意,如果用户转到另一个页面然后返回此页面,我希望此代码再次 运行,只要他们留在页面上就不会。

这是我的代码:

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

public partial class Chat : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!ScriptManager.GetCurrent(this.Page).IsInAsyncPostBack)
        {
            SendButton.Click += new EventHandler(SendButton_Click);
            if (Request.QueryString["RecID"] != null)
                Session["receivinguserid"] = Request.QueryString["RecID"];
            else
                Response.Redirect("~/Home.aspx");
            UserCredential sendingUser = (UserCredential)Session["authenticatedUser"];
            UserCredential receivingUser = Global.Users.Find(m => m.UserID == Convert.ToInt32(Session["receivinguserid"]));
            Conversation currentConversation = new Conversation((int)sendingUser.UserID, (int)receivingUser.UserID);
            if (sendingUser.Conversations.Find(m => m.ReceivingUserID == receivingUser.UserID) == null)
            {
                Global.Users.Find(m => m.Name == (string)Session["authenticatedUsersUsername"]).Conversations.Add(new Conversation((int)((UserCredential)Session["authenticatedUser"]).UserID, Convert.ToInt32(Session["receivinguserid"])));
                Global.Users.Find(m => m.UserID == Convert.ToInt32(Session["receivinguserid"])).Conversations.Add(new Conversation(Convert.ToInt32(Session["receivinguserid"]), (int)((UserCredential)Session["authenticatedUser"]).UserID));
            }
            else
            {
                currentConversation = sendingUser.Conversations.Find(m => m.ReceivingUserID == receivingUser.UserID);
                foreach (Message m in currentConversation.ReadMessageList)
                {
                    if (m.UserID == sendingUser.UserID)
                    {
                        ChatLabel.Text += "<br> " + sendingUser.Name.ToString() + ": " + m.MessageText + " " + m.MessageDate.ToString("dddd, dd MMMM HH:mm");
                    }
                    else if (m.UserID == receivingUser.UserID)
                    {
                        ChatLabel.Text += "<br>" + receivingUser.Name.ToString() + ": " + m.MessageText + " " + m.MessageDate.ToString("dddd, dd MMMM HH:mm");
                    }
                }
                foreach (Message m in sendingUser.Conversations.Find(m => m.ReceivingUserID == receivingUser.UserID).UnReadMessageList)
                {
                    ChatLabel.Text += "<br>" + receivingUser.Name.ToString() + ": " + m.MessageText + " " + m.MessageDate.ToString("dddd, dd MMMM HH:mm");
                    sendingUser.Conversations.Find(t => t.ReceivingUserID == receivingUser.UserID).ReadMessageList.Add(m);
                }
                sendingUser.Conversations.Find(m => m.ReceivingUserID == receivingUser.UserID).UnReadMessageList.Clear();
            }
        }
    }
    public void UpdateChat(object sender, EventArgs e)
    {
        UserCredential sendingUser = (UserCredential)Session["authenticatedUser"];
        UserCredential receivingUser = Global.Users.Find(m => m.UserID == Convert.ToInt32(Session["receivinguserid"]));
        foreach (Message m in sendingUser.Conversations.Find(c => c.ReceivingUserID == receivingUser.UserID).UnReadMessageList)
        {
            ChatLabel.Text += "<br>" + receivingUser.Name.ToString() + ": " + m.MessageText + " " + m.MessageDate.ToString("ddd, dd MMMM HH:mm");
            Global.Users.Find(u => u.UserID == (int)sendingUser.UserID).Conversations.Find(t => t.ReceivingUserID == receivingUser.UserID).ReadMessageList.Add(m);
        }
        Global.Users.Find(m => m.UserID == (int)sendingUser.UserID).Conversations.Find(t => t.ReceivingUserID == receivingUser.UserID).UnReadMessageList.Clear();
    }

和HTML:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Chat.aspx.cs" Inherits="Chat" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
  <a>
  <asp:ScriptManager ID="ScriptManager1" runat="server">
  </asp:ScriptManager>
   <asp:Timer ID="Timer1" runat="server">
   </asp:Timer>
  </a>
  <asp:UpdatePanel runat="server">
   <Triggers>
    <asp:AsyncPostBackTrigger ControlID="tim" EventName="Tick" />
   </Triggers>
   <ContentTemplate>
    <asp:Timer ID="tim" Interval="5000" Enabled="true" OnTick="UpdateChat" runat="server"></asp:Timer>
    <asp:Label ID="ChatLabel" runat="server"></asp:Label>
   </ContentTemplate>
  </asp:UpdatePanel>
  <asp:TextBox ID="MessageTextBox" runat="server"></asp:TextBox>
  <asp:Button ID="SendButton" runat="server" Text="Send" OnClientClick="return false"/>
    </div>
    </form>
</body>
</html>

当代码为第一个 运行 时设置一个会话变量,如果会话变量为空则仅 运行 代码。

当代码第一个 运行s 时它将为空,但在其余时间不为空。

if(!IsPostback)
{

 // code to run only once

}

IsPostback 检查您是第一次传递它 => (IsPostback = false) 还是作为触发事件稍后出现的回发的结果 => (IsPostback = true),在上面的代码中我们正在使用 ! 反转 IsPostback 以使错误的情况落到实处。有关更多详细信息,请查看此 IsPostback Explained