我有一个定时器设置,在用户点击按钮后4秒触发,除了在OnTimedEvent中我需要将用户重定向到另一个网页。这是我到目前为止所做的:
在按钮的onClick
事件中:
System.Timers.Timer aTimer = new System.Timers.Timer();
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 4000;
aTimer.Enabled = true;
然后在OnTimed Event()
我有:
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
Response.Redirect("~/Account/DeleteAccount.aspx");
}
我也试过
HttpContext.Current.Response.Redirect("~/Account/DeleteAccount.aspx");
在OnTimedEvent
但没有运气。
答案 0 :(得分:2)
发布页面后,发送重定向为时已晚:响应已经发送,因此您拥有的响应对象不再有效。
相反,您需要使用类似
的客户端脚本代码处理它window.setTimeout(function() { window.location.href = "~/Account/DeleteAccount.aspx"; }, 4000);
或在响应中设置Refresh标头,告诉客户端当时需要加载不同的页面。
此外,从这样的页面内实例化一个计时器可能是一个坏主意 - 除了它持有一个无效的响应对象这个事实,即使访问者关闭页面,计时器也会挂起,而且它相当昂贵系统资源方面的对象。
答案 1 :(得分:0)
标准异步模型在单个Web响应的上下文中确实不能很好地工作。当您完成设置计时器时,您执行的方法将继续执行,这意味着它将完成构建响应,然后它将发送它(它将有时间在4秒内完成所有这些,很可能)。因此,在计时器触发时,响应已经发送并结束。 HTTP的设计是,一旦请求结束,您就无法发送更多内容,它最终会被忽略。
你有几个选择。一种是确保响应不会发送4秒钟。 (这意味着而不是使用计时器,只需使用阻塞等待4秒的Thread.Sleep
之类的东西。)另一种方法是让响应被发送,但要使用JavaScript或其他客户端代码来设置计时器并执行重定向在4秒内。如果你有一个你想要在等待时呈现的页面,那么第二个选项是必需的,如果你只是希望用户在服务器正在做某事时观察浏览器旋转,那么第一个选项就是最好的。
如果您的目标不是等待4秒,而是要运行一些长时间运行的任务,并且此计时器试图等待它完成,那么您需要更改该设计。在Web环境中,您最好直接在当前线程中运行长时间运行的任务(假设长时间运行是一两秒,而不是几分钟/小时),因为您希望阻止该线程继续它的业务。如果你启动一个新线程来完成工作,你就不能依赖于能够影响响应(所以如果它从不影响响应就可以新建一个线程)。如果您的请求真的很长,或者您希望在客户端完成之前向客户端显示某些内容,那么您将需要使用AJAX在长时间运行的任务完成之前发送响应,然后使用它继续向服务器发送新请求,以便在长时间运行的任务生成结果后,它可以更新页面。 Here是展示这种技术的一个很好的例子。
答案 2 :(得分:0)
据我所知(这部分我可能完全错了)这段代码毫无意义。 HttpContext.Current
让我觉得这与ASP.NET有关,看到代码在c#中,我也猜测它是服务器代码。
在正常情况下(不使用计时器),如果您在服务器上进行重定向;这是大致发生的事情:
Response.Redirect
被称为Response.Redirect
方法的URL。现在,在第4点之后,无法告诉浏览器在其他地方导航(如果您不使用某种形式的服务器发送事件,通常使用长池或COMET)。
所以,问题就在这里,而不是在第3点调用Response.Redirect
,而是启动一个计时器。会发生什么事情:
过了一段时间
除非您在单击按钮时需要运行其他服务器端代码,否则可以使用javascript onclick轻松实现。这样的事情:window.setTimeout(function(){window.location = 'newLocation.aspx....';}, 4000/*4 sec*/);