【问题标题】:Hosting a long running process in IIS在 IIS 中托管一个长时间运行的进程
【发布时间】:2009-10-19 15:49:24
【问题描述】:

我有一个让我头疼的设计方案,我想知道哪种解决方案是最好的解决方案。

我有一个类似仪表板的应用程序,它从需要 Java RMI 连接来收集实时数据的服务中轮询信息。我想在 silverlight 中实现该仪表板组件并使用 WCF 提供数据。

过去,我使用 .net 远程处理和 Windows 表单为此设计了一个解决方案。我之前的设计是一个 Windows 服务,但我想知道是否有办法让我在 IIS 中托管这个服务,比如应用程序。

服务需要: -> 打开 RMI 连接(我已经用 ikvm 完成了) -> 定期拉取数据 ->更新客户端新数据已到达(观察者模式)

我可以实现我的数据收集类的单例实例并注册观察者吗?我应该只在 Windows 服务中托管 WCF 吗?还有其他想法吗?

【问题讨论】:

    标签: .net wcf silverlight iis


    【解决方案1】:

    Web 架构本质上只是响应请求。您可以通过来自客户端的重复轮询来模拟 PUSH,但如果客户端没有主动寻求信息,您就无法将其推送给他们。

    根据您的客户需求,听起来最好是带有后台缓存和轮询系统以保持更新的网络服务,因为您的客户总是会立即获得最新信息。缓存和更新可以由许多不同的解决方案维护,但您的客户端只能看到标准的 Web 服务。

    您可以通过将较小的界面作为 Web 服务的一部分来进一步增强它,以允许客户端在下载之前检查是否有更新。下载的大小会抵消往返检查更新的大小。

    【讨论】:

      【解决方案2】:

      IIS 旨在处理 HTTP 连接,这些连接通常是短暂的。为了做这种事情,你必须让客户端定期轮询服务器。

      【讨论】:

        【解决方案3】:

        如何实现这一点的完整示例...

        using System
        using Core.Services;
        using System.Threading.Tasks;
        using System.Web.Hosting;
        
        public interface IISHostedProcessService : IRegisteredObject, IDisposable
        {
            Task Start();
        }
        
        public class CoreHostedProcess : IISHostedProcessService
        {
            protected bool running;
        
            public CoreHostedProcess()
            {
        
            }
        
            public virtual Task Start()
            {
                return Task.Run(() =>
                {
                    running = true;
                    HostingEnvironment.RegisterObject(this);
                });
            }
        
            public virtual void Stop(bool immediate)
            {
                running = false;
                HostingEnvironment.UnregisterObject(this);
            }
        
            public virtual void Dispose()
            {
        
            }
        }
        

        好的,这就是定义的核心内容,现在我们定义一个托管进程来做一些有用的事情,比如嗯,按计划运行任务......

        using log4net;
        using System.Threading.Tasks;
        using System.Timers;
        using System;
        using Core.Utilities.Objects.Entities;
        using System.Linq;
        using System.Net.Http;
        using Core.Objects;
        using Ninject;
        
        
        public class TaskScheduler : CoreHostedProcess
        {
            static readonly ILog log = LogManager.GetLogger(typeof(TaskScheduler));
            Timer timer = new Timer(60000);
            IKernel kernel;
        
            public TaskScheduler(IKernel kernel) : base()
            {
                this.kernel = kernel;
            }
        
            async void RunTasks(object sender, ElapsedEventArgs e)
            {
                //TODO: write code to fetch tasks and run them
            }
        
            public override async Task Start()
            {
                log.Info("  Initialising Task Scheduler.");
                timer.Elapsed += RunTasks;
                RunTasks(null, null);
                timer.Start();
                await base.Start();
            }
        
            public override void Stop(bool immediate)
            {
                log.Info("  Stopping Task Scheduler.");
                timer.Stop();
                base.Stop(immediate);
            }
        }
        

        现在可以使用托管进程...

        在 IIS 中,在应用程序高级设置中将“preload enabled”设置为 true,以确保应用程序在初始加载后仍保持加载在服务器上。

        当应用加载时,例如,如果在旧式全局 asax 文件中使用 owin /,您可以添加以下内容...

        public class Startup
        {
            static readonly ILog log = LogManager.GetLogger(typeof(Startup));
            public static IKernel Kernel { get; private set; }
            static List<IISHostedProcessService> hostedProcesses = new List<IISHostedProcessService>();
        
            public void Configuration(IAppBuilder app) 
            {
                hostedProcesses.Add(new TaskScheduler());
            }
        }
        

        现在您应该拥有从 IIS 托管的 C# 应用程序中定义和初始化 TaskScheduler 所需的一切,我使用位于我的 EF 托管数据库顶部的 OData 构建了一个用于管理任务数据的 API,因此我可以CRUD 管理系统中的任务集。

        部署后,我相信我必须通过简单地向应用程序发出请求(任何 url)至少点击一次应用程序,一旦加载 IIS 将保持它运行(从而保持你的托管进程运行),直到你停止 IIS 应用程序托管进程。

        当应用程序停止时,将在您的托管进程上调用 Stop 方法,该方法“取消注册托管进程”并将其释放到服务器上,从而将托管进程与 IIS 应用程序生命周期联系起来。

        我认为也发布 OData 和 EF 代码有点过分。 希望这应该可以。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-24
          相关资源
          最近更新 更多