2009-10-19 85 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代碼太多了。 希望這應該做。

相關問題