繁体   English   中英

MVC代码以查看控制器是否仍在使用中

[英]MVC code to see whether or not a Controller is still in use

在我的MVC应用程序中,我有一个控制器,该控制器创建Model对象的实例。 Model ,我有一个计时器,该计时器每700ms执行一次功能。 当我在网站上运行控制器时,即使关闭浏览器窗口,我仍然可以看到计时器正在运行。 (计时器启动/停止串行端口连接,并且我有一个指示灯,指示何时进行通讯)。

在我完全重新启动IIS之前,通信实际上永远不会停止。

有什么方法可以检查控制器是否仍在使用中,如果控制器不再处于活动状态,则可以停止计时器?

这是模型代码:

public CheckPulses(int interval) {
    CheckPulsesTimer(interval);   
}

public void CheckPulsesTimer(int interval) {
    Timer timer = new Timer();
    timer.Enabled = true;
    timer.AutoReset = true;
    timer.Interval = interval;
    timer.Elapsed += new ElapsedEventHandler(GetPulses);
}

这是控制器代码:

public ActionResult Index() {
    CheckPulses Pulses = new CheckPulses(700);
    return View();
}

我想也许我应该只向GetPulses事件添加一些东西,该事件在每次定时器间隔到期时发生,并检查该控制器是否仍在使用中。 如果不是,请停止计时器。 但是,我不确定如何写支票。 谁能指出我正确的方向?

我认为这里的核心问题在于您对“正在使用”的控制器的理解。

似乎您正在想象以下内容:

  1. 用户输入您的URL,浏览器将连接到服务器。
  2. 服务器将请求路由到MVC控制器,该控制器与浏览器保持连接,并使用此连接响应每个后续请求。
  3. 用户关闭他们的浏览器,或导航离开-然后Controller关闭连接并进行处理。

但是,实际情况并非如此。 Web流量通常是一系列隔离的,单独的请求/响应配对。 浏览器和服务器之间没有正在进行的连接。

更正确的顺序如下所示:

  1. 用户输入您的URL,然后浏览器通过端口80(或https的443)连接到您的服务器,传入有效的HTTP请求,其中包含URL,HTTP动词和其他信息。
  2. 您的服务器使用HTTP请求的信息将请求路由到特定的可执行代码段(在这种情况下,是Controller的特定Action方法)。
  3. 为了执行,服务器创建了Controller的Instance,然后使用HTTP请求的信息作为参数来触发它的Action方法。
  4. 您的Controller代码将执行,并且HTTP响应消息将发送回浏览器。
  5. ControllerControllerFactory .Dispose()

您遇到的问题不是由Controller处于“活动状态”引起的-因为那不是Controller所做的。 相反,您正在Model创建一个Timer ,因此该Model继续存在于内存中,无法被GarbageCollection杀死。 有关更多详细信息,请参见此答案

本质上,应这样考虑:

您的Controller正在充当工厂。 当您调用其Index方法时,等效于告诉工厂“生产1个Model ”。 Model推出工厂后,工厂可以自由关闭,关闭灯,并将所有工人送回家( Controller.Dispose() 'd)。

但是, Model仍然存在于内存中。 在大多数情况下,一旦超出范围,该Model应该由于GarbageCollection而消失-但由于其中有一个活动的Timer ,因此某些东西阻止了该进程的执行-因此该Model继续存在于服务器的内存中,在每次计时器到期时愉快地一次又一次地触发其代码。

请注意,这无关与用户是否仍是您的网站,或者他们的浏览器是否仍处于打开状态等,与变量范围和性质做GarbageCollection的服务器上。 现在,您已经开始了一个过程,该过程将继续直到被告知停止。

潜在的解决方案:

为了解决此问题,您可以考虑以下因素:

  1. Singleton对象中创建您的Timer 就像是:

     public static class ConnectionManager { private static bool initialized = false; private static DateTime lastStartedAt = DateTime.Now; private static Timer timer = null; private static void Initialize() { if (timer == null) { timer = new Timer() { AutoReset = true, }; timer.Elapsed += new ElapsedEventHandler(GetPulses); } } public static void Start(int interval) { lastStartedAt = DateTime.Now; Initialize(); // Create a timer if necessary. timer.Enabled = true; timer.Interval = interval; } public static void Stop() { timer.Enabled = false; } } 
  2. 将您的Controller更改为以下内容:

     public ActionResult Index() { ConnectionManager.Start(700); return View(); } 
  3. 处理Timer事件的到期时,请检查lastStartedAt事件发生多久了。 如果超过X分钟,则不进行处理,并触发ConnectionManager.Stop()

这将使您能够在滚动到期时保持串行活动轮询。 换句话说,每次用户请求您的“ Index页面时,您将刷新计时器,并确保您正在收听。 但是,在X分钟后,如果没有用户提出请求-您只需关闭计时器和相关的端口即可。

您可能没有停止或处置计时器。 这将导致它不会被垃圾回收,并在应用程序保持运行期间保持活动状态。

您应该在Controller的Dispose方法中停止并处置Timer。

您有几种选择:

  1. 在控制器上重写Dispose方法,并通过调用Pulses.Dispose()处置模型。
  2. 在控制器上重写OnActionExecuted方法并进行处理
  3. 创建自定义动作过滤器并实现OnActionExecuted方法,并将其分配给控制器或动作。(您可以将对模型的引用放入TempData,然后在ActionFilter中检查是否filterContext.Controller.TempData [“ MyReferenceToModel”]!= null ,然后使用它配置计时器)
  4. 在模型中实现IDisposable接口,并在using语句中使用它

希望这会有所帮助,迪玛

您可以使用JQuery + MVC停止Timer。

jQuery可以响应页面的unload事件,如下所示:

$(window).unload(function() {
  alert('Handler for .unload() called.');
});

您可以对控制器进行ajax调用。 我们还需要创建一个属性来访问计时器。 我假设您将计时器属性称为MyTimer

Timer MyTimer { get; set; }

因此,您需要创建一个返回void并调用Timer的Stop()方法的控制器。 [HttpPost] public void KillTimer(){MyTimer.Stop(); }

现在,如果将Ajax调用添加到我们先前创建的卸载事件中,那么只要页面关闭,我们就应该能够终止计时器。

$.ajax(
{
   type: "POST",
   url: "/Home/Index",
   ,
   success: function(result)
    {
        alert("Timer Closed");
    },                
   error : function(req, status, error)
   {
        alert("Sorry! We could not receive your feedback at this time.");   
   }
});

成功和错误功能不是必需的。 我包括它们只是为了演示。 我也猜到您的控制器名称为Home。 如果URL不同,则需要更新URL。 您可以使用纯JavaScript执行此操作。 JQuery可以帮助您避免编写大量繁琐的浏览器兼容性代码。 (我听说歌剧在卸载部分很痛苦)

为了解决潜在的浏览器崩溃和意外事件的问题,您可以连接控制器以检查计时器是否超过了最大时间限制。

祝好运 !

资料来源:

jQuery Unload()

使用jQuery从JavaScript调用ASP.NET MVC操作

jQuery Ajax()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM