ASP.NET C# AJAX 控件倒数计时器仅在对未来时间进行硬编码时才有效

ASP.NET C# AJAX Control Countdown Timer Works Only When Future Time is Hardcoded

我有一个 AJAX C# ASP.NET 控件并且它工作正常(仅当日期时间被硬编码时从当前时间开始倒计时 2 小时。我想将日期作为变量传递但每次我这样做时,计时器都会停止工作。

这是有效的...

 protected void Timer1_Tick(object sender, EventArgs e)
    {
        String DateTimeFuture = DateTime.Now.AddHours(2).ToString();
        DateTime NeededByDateTime = DateTime.Parse("03/18/2017 10:00:00 AM");
        TimeSpan time1 = new TimeSpan();
        time1 = NeededByDateTime - DateTime.Now;
        if ((time1.Hours == 0) && (time1.Minutes == 0) && (time1.Seconds == 0))
        {
            Label1.Text = "Time Expired!";
            //Return article to results
        }
        else
        {
            string countDown = string.Format("{0} Days, {1} Hours, {2} Minutes, {3} Seconds til launch.", time1.Days, time1.Hours, time1.Minutes, time1.Seconds);
            Label1.Text = countDown.ToString();
        }

    }

这是行不通的...

protected void Timer1_Tick(object sender, EventArgs e)
    {
        String DateTimeFuture = DateTime.Now.AddHours(2).ToString();
        DateTime NeededByDateTime = DateTime.Parse(DateTimeFuture);
        TimeSpan time1 = new TimeSpan();
        time1 = NeededByDateTime - DateTime.Now;
        if ((time1.Hours == 0) && (time1.Minutes == 0) && (time1.Seconds == 0))
        {
            Label1.Text = "Time Expired!";
        }
        else
        {
            string countDown = string.Format("{0} Days, {1} Hours, {2} Minutes, {3} Seconds til launch.", time1.Days, time1.Hours, time1.Minutes, time1.Seconds);
            Label1.Text = countDown.ToString();
        }

    }

关于为什么它不适用于第二段代码的任何想法?

更新:

如果您想尝试让示例适用于您的环境,您需要在页面中添加以下代码。

 <form method="post" runat="server" action="Page.aspx">
                <asp:ScriptManager ID="ScriptManager1" runat="server" />

            <asp:UpdatePanel ID="UpdatePanel1" Visible="true" runat="server" >
                <ContentTemplate>
                    <asp:Timer ID="Timer1" runat="server" Interval="1000" OnTick="Timer1_Tick">
                    </asp:Timer>
                    <asp:Label ID="Label1" runat="server"></asp:Label>
                </ContentTemplate>
            </asp:UpdatePanel>
</form>

到底是什么不起作用?它是否抛出异常。解析日期后 contentNeededByDateTime 变量的值是多少?正确吗?

当前文化可能存在问题。因此,为确保将正确的格式传递给解析器,而不是 ToString(),请使用一些显式格式:http://www.csharp-examples.net/string-format-datetime/

我假设这只是一个测试代码,您将把变量作为字符串参数传递。所以你只需要确保以正确的格式传递值。

更新

根据下面的评论,我对这个问题有了更多的了解。您不能在方法内声明日期,因为每次调用此方法时它都会更新,这可能是每秒一次。如果您希望能够为每个用户进行倒计时。通过定时器获取用户请求页面的日期和时间,保存到Session中:

Session["NeededByDateTime"] = DateTime.Now.AddHours(2);

然后该方法将如下所示:

protected void Timer1_Tick(object sender, EventArgs e)
{
    //for the sake of simplicity but you should check if it exists first
    DateTime NeededByDateTime = (DateTime)Session["NeededByDateTime"]; 

    time1 = NeededByDateTime - DateTime.Now;
    if ((time1.Hours == 0) && (time1.Minutes == 0) && (time1.Seconds == 0))
    {
        Label1.Text = "Time Expired!";
    }
    else
    {
        string countDown = string.Format("{0} Days, {1} Hours, {2} Minutes, {3} Seconds til launch.", time1.Days, time1.Hours, time1.Minutes, time1.Seconds);
        Label1.Text = countDown.ToString();
    }

}

您的示例不起作用,因为每次 Timer 调用 Tick 方法时 time1 总是等于 2 小时。

protected void Timer1_Tick(object sender, EventArgs e)
{
    String DateTimeFuture = DateTime.Now.AddHours(2).ToString(); // NOW + 2 HOURS
    DateTime NeededByDateTime = DateTime.Parse(DateTimeFuture);
    TimeSpan time1 = new TimeSpan();
    time1 = NeededByDateTime - DateTime.Now; // NOW + 2 HOURS - NOW = 2 HOURS
    if ((time1.Hours == 0) && (time1.Minutes == 0) && (time1.Seconds == 0))
    {
        Label1.Text = "Time Expired!";
    }
    else
    {
        string countDown = string.Format("{0} Days, {1} Hours, {2} Minutes, {3} Seconds til launch.", time1.Days, time1.Hours, time1.Minutes, time1.Seconds);
        Label1.Text = countDown.ToString();
    }
}

您应该在 Tick 方法之外声明 NeededByDateTime 变量,这样它就保持不变,不会在每次报价时更新。

private DateTime NeededByDateTime = DateTime.Now.AddHours(2); //.., or whatever you want 

protected void Timer1_Tick(object sender, EventArgs e)
{
    TimeSpan time1 = NeededByDateTime - DateTime.Now;
    if ((time1.Hours == 0) && (time1.Minutes == 0) && (time1.Seconds == 0))
    {
        Label1.Text = "Time Expired!";
    }
    else
    {
        string countDown = string.Format("{0} Days, {1} Hours, {2} Minutes, {3} Seconds til launch.", time1.Days, time1.Hours, time1.Minutes, time1.Seconds);
        Label1.Text = countDown.ToString();
    }
}