[英]WCF singleton hosted in windows service. How to auto start WCF without first “touching” the service with client
[英]How to initialize singleton class in Windows Service Hosted WCF Service on startup
我寫了Windows服務托管WCF服務。 服務行為是: [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
我從數據庫讀取一些數據,並在啟動時創建一些共享類。 即使沒有請求,也有一些計時器應該工作。 初始化也需要一些時間。
所有這些初始化都發生在另一個dll中的單例類中。 我嘗試這里描述的不同signleton類初始化。
但是單例類直到第一個請求到達時才初始化。 計時器,從DB ...等加載的對象。所有這些都在此singleton類中。 在第一個請求到達后,一切正常。 即使類未初始化,服務似乎也可以在“服務”窗口上運行。
在請求到達之前的調試器中,dll甚至不會加載。 我如何在啟動時初始化此單例類?
這是服務行為問題還是我應該更換Windows Service安裝程序?
編輯:重新格式化問題。
您可以在OnStart Windows服務事件上啟動WCF服務,並在OnStop Windows事件上停止它。 您可以向Windows事件日志中添加一些診斷信息,以查看是否有任何異常,並檢查服務是否被啟動等。
using System;
using System.ServiceModel;
using System.ServiceProcess;
using System.Diagnostics;
using System.Configuration;
using System.Timers;
using System.Collections.Generic;
namespace MyWCF
{
public partial class WcfOverHttpService : ServiceBase
{
private ServiceHost m_host;
public WcfOverHttpService()
{
System.Diagnostics.EventLog.WriteEntry(" WCF Interface", " Constructor called.", EventLogEntryType.Information);
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
System.Diagnostics.EventLog.WriteEntry(" WCF Interface", "On Start called.", EventLogEntryType.Information);
StartWcfService();
}
catch (Exception ex)
{
System.Diagnostics.EventLog.WriteEntry(" WCF Interface","On Start failed :"+ex.ToString(), EventLogEntryType.Error);
throw ex;
}
}
private void StartWcfService()
{
try
{
System.Diagnostics.EventLog.WriteEntry(" WCF Interface", "Start Wcf Service.", EventLogEntryType.Information);
m_host = new ServiceHost(typeof(MyWCFService));
m_host.Open();
System.Diagnostics.EventLog.WriteEntry(" WCF Interface", "WCF Service HostOpen.", EventLogEntryType.Information);
}
catch (Exception ex)
{
System.Diagnostics.EventLog.WriteEntry(" WCF Interface", "Start WCF Service failed :" + ex.ToString(), EventLogEntryType.Error);
throw ex;
}
}
protected override void OnStop()
{
try
{
System.Diagnostics.EventLog.WriteEntry(" WCF Interface", "On Stop called.", EventLogEntryType.Information);
if (m_host != null)
{
System.Diagnostics.EventLog.WriteEntry(" WCF Interface", "Stop WCF Service.", EventLogEntryType.Information);
m_host.Close();
m_host = null;
}
}
catch(Exception ex)
{
System.Diagnostics.EventLog.WriteEntry(" WCF Interface", "On Stop failed :" + ex.ToString(), EventLogEntryType.Error);
throw ex;
//handle exception
}
}
}
}
這是實現計時器邏輯的方式。
using System;
using System.ServiceModel;
using System.ServiceProcess;
using System.Diagnostics;
using System.Configuration;
using System.Timers;
using System.Collections.Generic;
namespace MyAppNameSpace
{
public partial class MyWCFService : ServiceBase
{
private ServiceHost m_host;
System.Timers.Timer MyProductionTimer = null;
bool _MyProductionRunOnce = false;
//// Put this values in Config
private string MyProductionSchedule = "DAILY";
private string MyProductionToRun = "MANY";
private string MyProductionStartTime = "10:00 PM";
private int MyProductionPollInterval = 60000;
public MyWCFService()
{
System.Diagnostics.EventLog.WriteEntry("My WCF Interface Constructor", " Constructor called.", EventLogEntryType.Information);
InitializeComponent();
//Create Timer Object and register tick event
this.MyProductionTimer = new System.Timers.Timer(MyProductionPollInterval);
this.MyProductionTimer.Elapsed += new ElapsedEventHandler(this.MyProductionTimer_Tick);
}
protected override void OnStart(string[] args)
{
try
{
System.Diagnostics.EventLog.WriteEntry("My WCF Interface Start", "On Start called.", EventLogEntryType.Information);
StartWcfService();
// Setup timer and start it
this.MyProductionTimer.Interval = MyProductionPollInterval;
this.MyProductionTimer.Enabled = true;
this.MyProductionTimer.Start();
System.Diagnostics.EventLog.WriteEntry("My MyProduction Timer Start", "MyProduction Timer Start At :" + DateTime.Now.ToString(), EventLogEntryType.Information);
}
catch (Exception ex)
{
System.Diagnostics.EventLog.WriteEntry("My WCF Interface Start Error","On Start failed :"+ex.ToString(), EventLogEntryType.Error);
throw ex;
}
}
protected override void OnStop()
{
try
{
System.Diagnostics.EventLog.WriteEntry("My WCF Interface Stop", "On Stop called.", EventLogEntryType.Information);
//Stop the timer
this.MyProductionTimer.Stop();
System.Diagnostics.EventLog.WriteEntry("My MyProduction Timer Stop", "MyProduction Timer Stopped At :" + DateTime.Now.ToString(), EventLogEntryType.Information);
if (m_host != null)
{
System.Diagnostics.EventLog.WriteEntry("My WCF Interface Stopped", "Stop Wc fService.", EventLogEntryType.Information);
m_host.Close();
m_host = null;
}
}
catch(Exception ex)
{
System.Diagnostics.EventLog.WriteEntry("My WCF Interface Stop Error", "On Stop failed :" + ex.ToString(), EventLogEntryType.Error);
throw ex;
//handle exception
}
}
//Timer Tick Event
private void MyProductionTimer_Tick(object sender, EventArgs e)
{
this.MyProductionTimer.Stop();
this.MyProductionTimer.Interval = MyProductionPollInterval;
bool runFlag = false;
try
{
// Find out if it is time to run logic based on schedule
string dw = DateTime.Now.DayOfWeek.ToString();
if ((MyProductionSchedule.ToUpper() == "DAILY" && MyProductionToRun.ToUpper() == "ONCE") ||
(MyProductionSchedule.ToUpper() == dw.ToUpper() && MyProductionToRun.ToUpper() == "ONCE"))
{
if (checkPolTime(MyProductionStartTime))
_MyProductionRunOnce = true;
if (_MyProductionRunOnce)
{
_MyProductionRunOnce = false;
runFlag = true;
}
}
else if ((MyProductionSchedule.ToUpper() == "DAILY" && MyProductionToRun.ToUpper() == "MANY") ||
(MyProductionSchedule.ToUpper() == dw.ToUpper() && MyProductionToRun.ToUpper() == "MANY"))
{
if (!_MyProductionRunOnce)
{
if (checkPolTime(MyProductionStartTime))
_MyProductionRunOnce = true;
}
if (_MyProductionRunOnce)
runFlag = true;
}
else
{
_MyProductionRunOnce = false;
}
if (runFlag)
{
// Your Timer Business Logic goes here
}
}
catch (Exception exc)
{
System.Diagnostics.EventLog.WriteEntry(" MyProduction Timer Error",
exc.Message, EventLogEntryType.Error);
}
finally
{
this.MyProductionTimer.Start();//To restart the processing of production
}
}
private void StartWcfService()
{
try
{
System.Diagnostics.EventLog.WriteEntry("My WCF Interface Create Host", "Start Wcf Service.", EventLogEntryType.Information);
m_host = new ServiceHost(typeof(WcfService));
m_host.Open();
System.Diagnostics.EventLog.WriteEntry("My WCF Interface Host Opened", "WCF Service HostOpen.", EventLogEntryType.Information);
}
catch (Exception ex)
{
System.Diagnostics.EventLog.WriteEntry("My WCF Interface Exception", "Start WCF Service failed :" + ex.ToString(), EventLogEntryType.Error);
throw ex;
}
}
// Utility to check if it is time to run the timer logic
public static bool checkPolTime(string ProdStartTime)
{
DateTime t1 = DateTime.Now;
DateTime t2 = Convert.ToDateTime(ProdStartTime);
int i = DateTime.Compare(t1, t2);
if (i >= 0)
{
return true;
}
else
{
return false;
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.