
[英]How to process long running requests with an HTTP handler under 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.