2009-10-19 87 views
1

我有一个设计场景给了我几个头痛,我想知道什么解决方案是最好的解决方案。在IIS中托管一个长时间运行的进程

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

我以前用.net remoting和Windows窗体为此设计了一个解决方案。我以前的设计是一个Windows服务,但我想知道是否有办法让我像IIS中的应用程序一样托管此服务。

的服务需要: - >打开RMI连接(这我已经做IKVM) - >定期 提取数据 - >更新客户端新的数据已经到达(观察者模式)

莫非

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

回答

1

Web架构本质上只是对请求做出响应。您可以通过客户端重复轮询模拟PUSH,但如果客户端不主动寻找信息,则无法将其推送到客户端。

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

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

0

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

0

如何实现这个完整的示例...

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中,应用先进的设置中设置“预加载启用”为真,以确保应用程序内保持在服务器上装载后初始负载。

当应用程序加载时,例如,如果使用owin /在老同学全球ASAX文件,你可以添加以下...

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()); 
    } 
} 

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

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

当应用程序停止时,托管进程将调用Stop方法,“取消注册托管进程”并将其丢弃到服务器上,从而将托管进程绑定到IIS应用程序生命周期。

我觉得发布OData和EF代码太多了。 希望这应该做。

相关问题