繁体   English   中英

在IIS中托管长时间运行的进程

[英]Hosting a long running process in IIS

我的设计方案使我有些头疼,我想知道哪种解决方案是最佳解决方案。

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

过去,我已经使用.net远程处理和Windows窗体设计了一种解决方案。 我以前的设计是Windows服务,但我想知道是否有办法在IIS中托管此服务,例如应用程序。

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

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

Web体系结构本质上只是关于响应请求。 您可以通过反复从客户端轮询来模拟PUSH,但是如果客户端没有主动寻找信息,则无法将其推送到客户端。

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

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

IIS被设计为处理HTTP连接,并且这些连接通常是短暂的。 为了执行这种操作,您必须使客户端定期轮询服务器。

如何实现此目标的完整示例...

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()
    {

    }
}

好的,这就是定义的核心内容,现在我们定义一个托管进程来执行一些有用的操作,例如um,按计划运行任务...

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中,在应用程序高级设置中,将“已启用预加载”设置为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代码也太过分了。 希望这应该做。

暂无
暂无

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

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