Я создал службу windows с таймером в С#.net. он отлично работает, когда я отлаживаю/создаю проект в 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 Service нелегкий.
Давным-давно я написал службу С#.
Это логика класса 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, необходимо ресурсы не будут создаваться снова во второй раз, когда служба называется.
Здесь приведен рабочий пример, в котором запуск службы запускается в OnTimedEvent таймера, который реализован как делегат в классе ServiceBase, а логика таймера инкапсулируется в методе 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();
}
...
}
Интервал определяется в app.config в минутах:
<userSettings>
<MyProject.Properties.Settings>
<setting name="Interval" serializeAs="String">
<value>1</value>
</setting>
</MyProject.Properties.Settings>
</userSettings>