[英]Windows service with timer
我在c#.net中創建了一個帶有計時器的Windows服務。 它在Visual Studio中調試/構建項目時工作正常,但安裝后它不執行其操作。
這背后可能是什么原因?
代碼:
public partial class Service1 : ServiceBase
{
FileStream fs;
StreamWriter m_streamWriter;
Timer tm = new Timer();
public Service1()
{
InitializeComponent();
this.ServiceName = "timerservice";
tm.Interval = 2000;
tm.Tick += new EventHandler(PerformOperations);
tm.Start();
fs = new FileStream(@"c:\mcWindowsService.txt", FileMode.OpenOrCreate, FileAccess.Write);
m_streamWriter = new StreamWriter(fs);
m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
}
private void PerformOperations(object sener, EventArgs e)
{
//StreamWriter swr = new StreamWriter("c:\\test_from_database.txt",true);
try
{
OdbcConnection con = new OdbcConnection("DSN=liquor_data");
OdbcDataAdapter adp = new OdbcDataAdapter("", con);
DataSet ds = new DataSet();
string sql = "select * from item_group";
adp.SelectCommand.CommandText = sql;
adp.Fill(ds, "item_group");
foreach (DataRow dr in ds.Tables["item_group"].Rows)
{
// swr.Write(dr["group_name"].ToString() + "\t\t" + DateTime.Now.TimeOfDay.ToString() + "\n");
//Console.WriteLine(dr["group_name"].ToString() + "\t\t" + DateTime.Now.TimeOfDay.ToString() + "\n");
m_streamWriter.WriteLine(dr["group_name"].ToString() + "\t\t" + DateTime.Now.TimeOfDay.ToString() + "\n");
}
m_streamWriter.Flush();
}
catch (Exception ex)
{
// swr.Write("Error :"+ ex.Message + "\t\t" + DateTime.Now.TimeOfDay.ToString() + "\n"); }
}
}
}
使用Windows服務的第一種方法並不容易..
很久以前,我寫了一個C#服務。
這是Service類的邏輯(測試,工作正常):
namespace MyServiceApp
{
public class MyService : ServiceBase
{
private System.Timers.Timer timer;
protected override void OnStart(string[] args)
{
this.timer = new System.Timers.Timer(30000D); // 30000 milliseconds = 30 seconds
this.timer.AutoReset = true;
this.timer.Elapsed += new System.Timers.ElapsedEventHandler(this.timer_Elapsed);
this.timer.Start();
}
protected override void OnStop()
{
this.timer.Stop();
this.timer = null;
}
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
MyServiceApp.ServiceWork.Main(); // my separate static method for do work
}
public MyService()
{
this.ServiceName = "MyService";
}
// service entry point
static void Main()
{
System.ServiceProcess.ServiceBase.Run(new MyService());
}
}
}
我建議您在一個單獨的靜態方法中編寫您的實際服務工作(為什么不在控制台應用程序中添加對它的引用),以簡化調試和清理服務代碼。
確保間隔足夠,並且僅在OnStart和OnStop覆蓋中寫入日志。
希望這可以幫助!
您需要將主代碼放在OnStart
方法上。
我的另一個答案可能有所幫助。
您需要放置一些代碼以在visual-studio中啟用調試,同時保持您的應用程序作為Windows服務有效。 這個其他SO線程涵蓋了調試Windows服務的問題。
編輯 :
另請參閱提供的文檔這里的OnStart
在MSDN方法,人們可以這樣說的:
不要使用構造函數來執行應該在OnStart中的處理 。 使用OnStart處理服務的所有初始化。 構造函數在應用程序的可執行文件運行時調用,而不是在服務運行時調用。 可執行文件在OnStart之前運行。 例如,當您繼續時,不會再次調用構造函數,因為SCM已將對象保存在內存中。 如果OnStop釋放在構造函數而不是OnStart中分配的資源,則第二次調用服務時將不會再次創建所需的資源。
這是一個工作示例,其中服務的執行是在Timer的OnTimedEvent中啟動的,它在ServiceBase類中實現為委托,Timer邏輯封裝在名為SetupProcessingTimer()的方法中:
public partial class MyServiceProject: ServiceBase
{
private Timer _timer;
public MyServiceProject()
{
InitializeComponent();
}
private void SetupProcessingTimer()
{
_timer = new Timer();
_timer.AutoReset = true;
double interval = Settings.Default.Interval;
_timer.Interval = interval * 60000;
_timer.Enabled = true;
_timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
}
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
// begin your service work
MakeSomething();
}
protected override void OnStart(string[] args)
{
SetupProcessingTimer();
}
...
}
Interval在app.config中以分鍾為單位定義:
<userSettings>
<MyProject.Properties.Settings>
<setting name="Interval" serializeAs="String">
<value>1</value>
</setting>
</MyProject.Properties.Settings>
</userSettings>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.