ASP.NET Web 应用程序中,使用哪种方法实现每 5 分钟调用一次函数的计时器?PageLoad 中没有 main() 吗?

In ASP.NET web application, in which method do I implement a timer that calls a function every 5 minutes? There's no main() could it be in PageLoad?

提问人:kvj 提问时间:8/19/2022 更新时间:8/19/2022 访问量:621

问:

我有一个 ASP.NET Web 应用程序,在.aspx.cs文件中,我必须每 10 分钟调用一个名为 RefreshData() 的函数,该函数基本上使用 Databind() 更新 Gridview、Gridvew1。

在 PageLoad 方法中,我有一些代码应该使用计时器每 5 分钟调用一次 RefreshData(),但它似乎不起作用

aTimer = new System.Timers.Timer();
        aTimer.Interval = 1000 * 300;

        aTimer.Elapsed += OnTimedEvent;

        // Have the timer fire repeated events (true is the default)
        aTimer.AutoReset = true;

        // Start the timer
        aTimer.Enabled = true;


    }

    protected void OnTimedEvent(Object source, System.Timers.ElapsedEventArgs e)
    {
        RefreshData();
        Label3.Text = "The Elapsed event was raised at " + e.SignalTime.ToString();
    }

由于没有 Main() 方法,这个计时器可以在哪里实现?

谢谢。

C# asp.net 事件 GridView System.Timers.Timer

评论


答:

1赞 Albert D. Kallal 8/19/2022 #1

作为一般规则,您希望避免在网页中键入计时器类型。

请记住,值和隐藏的代码仅在短页面回发期间存在。一旦网页被发送到客户端,那么网页、代码中的变量和所有内容都会被转储并耗尽内存。Web 服务器现在正在等待来自任何用户的任何页面 - 而不仅仅是您的网页,它现在已经超出了范围。背后的代码消失了 - 非常像调用一个函数,在返回时,你刚刚调用的函数现在已经消失了。你必须考虑这样的网页。您可能有 10 个用户---但您只有一个 Web 服务器可以处理来自该用户的页面。

那么,在您的页面被发送到客户端之后?然后你所有的服务器端代码都消失了 - 超出了范围!- 不再存在!!

因此,让计时器运行的最简单方法是让网页以您想要的时间间隔回发。这必须在浏览器端级别进行。这意味着你卷起袖子编写 JavaScript,或者你可以使用一些内置的工具来做同样的事情(因此你可以使用一个浏览器端计时器控件来实现这个目的)。

因此,该代码隐藏页面中不能有一些计时器代码,因为该页面不再存在!!页面、代码、变量?在页面向下传输到客户端浏览器后,它们都消失了。在服务器端,您的页面代码被转储 - 消失了,不再存在!

这就是为什么我们称 Web 开发为无状态。运行后的代码和页面超出范围。正如我所说,一个很好的思考方式是当你调用一个函数时,函数退出 - 函数调用中的代码和值现在已经消失了。以这种方式考虑您的整个网页 - 一旦完成回发和往返,它就会超出范围。您没有为每个用户设置一个桌面,而是一个 Web 服务器,该服务器必须处理来自任何用户的任何页面。因此,一旦页面事件和处理完成,每个网页和该代码将不再存在,并且页面被发送回客户端。

所以,假设我们有这个网格:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
    DataKeyNames="ID" CssClass="table table-hover" width="40%">
    <Columns>
        <asp:BoundField DataField="FirstName" HeaderText="FirstName"  />
        <asp:BoundField DataField="LastName" HeaderText="LastName"  />
        <asp:BoundField DataField="HotelName" HeaderText="HotelName" />
        <asp:BoundField DataField="City" HeaderText="City"  />
        <asp:BoundField DataField="Description" HeaderText="Description"  />

        <asp:TemplateField HeaderText="" ItemStyle-HorizontalAlign="Center">
            <ItemTemplate>
                <button id="cmdDelete" runat="server" class="btn" 
                    onserverclick="cmdDelete_ServerClick" >
                    <span aria-hidden="true" class="glyphicon glyphicon-trash"> Delete</span> 
                </button>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

要加载的代码是这样的:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
            LoadGrid();
    }

    void LoadGrid()
    {
        string strSQL = @"SELECT * FROM tblHotelsA ORDER BY HotelName";
        using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
        {
            using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
            {
                conn.Open();
                DataTable rstData = new DataTable();
                rstData.Load(cmdSQL.ExecuteReader());
                GridView1.DataSource = rstData;
                GridView1.DataBind();
            }
        }
    }

我们现在有了这个:

enter image description here

好的,现在我们希望这个 gv 每 8 分钟刷新一次。

因此,在网页中,插入脚本管理器,然后放入计时器控件。

我们有这个:

enter image description here

现在,转到计时器上的事件,然后选择以下内容:

enter image description here

(您可以双击 On Tick 事件,将创建存根背后的代码。

所以,现在我们有了这个:

    protected void Timer1_Tick(object sender, EventArgs e)
    {
        LoadGrid();
    }

因此,该代码存根现在将每 8 分钟触发一次

(8 x 60 = 840 x 1000)

指定的时间为每 1000 毫秒(因此 1000 = 1 秒)。

评论

0赞 kvj 8/19/2022
谢谢!这完全解决了我的问题!这是您的回答第三次解决我的问题,非常感谢您的帮助。