Assembla обеспечивает Wiki, билеты и другие вещи бесплатно, и позволяет интеграция GitHub . Если Вы не хотите использовать GitHub, можно использовать плоскость Мерзавец с Assembla (со всеми положительными героями, которых Вы получаете с любым другим проектом).
Оценка является дешевой, также (" 2$ на члена команды в месяц").
Обычно я использую таймер, а затем останавливаю его, когда процесс запускается.
Вот статья, которая объясняет , как это сделать .
В моей компании мы полагаемся на планировщик задач Windows для запуска службы, а затем для ее завершения. Это гарантирует, что наша служба всегда будет работать в нужное время, а система планирования позволит сообщать об успехах / неудачах и т. Д.
You don't really want to use background worker. Background workers are used when you have something going one at the foreground (such as UI) and you also want something else to be done on the background. In your case there's no foreground processing, all you have is a single job that you need to run every once in a while.
Also, don't bother with the sleeping business etc. Instead, use a scheduler framework, such as Quartz.NET to wake it up every once in a while. This way when your service starts it will initialize the scheduler and do absolutely nothing until scheduler wakes up. When scheduler wakes up it will call a method of an object that you tell it to call when you initialize it.
This way the service will barely consume any CPU when idle and work full steam when needed.
Как насчет чего-то более похожего:
public class LongRunningService : ServiceBase
{
System.Threading.Thread processThread;
System.Timers.Timer timer;
private Boolean Cancel;
protected override void OnStart(string[] args)
{
timer = new Timer(Settings.Default.SleepTimeHours * 3600000);
timer.Elapsed += new ElapsedEventHandler(timer_Tick);
timer.Start();
Cancel = false;
}
protected override void OnContinue()
{
timer.Start();
}
protected override void OnPause()
{
timer.Stop();
}
protected override void OnStop()
{
if (processThread.ThreadState == System.Threading.ThreadState.Running)
{
Cancel = true;
// Give thread a chance to stop
processThread.Join(500);
processThread.Abort();
}
}
void timer_Tick(object sender, EventArgs e)
{
processThread = new System.Threading.Thread(new ThreadStart(DoWork));
processThread.Start();
}
private void DoWork()
{
try
{
while (!Cancel)
{
if (Cancel) { return; }
// Do General Work
System.Threading.Thread.BeginCriticalRegion();
{
// Do work that should not be aborted in here.
}
System.Threading.Thread.EndCriticalRegion();
}
}
catch (System.Threading.ThreadAbortException tae)
{
// Clean up correctly to leave program in stable state.
}
}
}
This is not a very good idea, since you lock your thread for the full period of "SleepTimeHours" and you won't be able to even stop the service in the meantime.
You could either make this service so that it would sleep for e.g. 5 seconds and then check whether it's time to get back to work, and if not, sleep another 5 seconds (that would give you the necessary responsiveness, if you need to stop the service).
OR: you might be better off just writing a console app that can be scheduled using the Windows "scheduled tasks" feature in order to be run every x hours. That way, you won't be blocking or using any system resource if your app isn't doing anything......
Marc
Blog.StackOverflow.com has an interesting article on using cache expiration to handle periodic tasks:
http://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/
У меня было такое же обсуждение с коллегами около часа назад! Я выбрал вариант while (_isPolling), потому что мне нужно, чтобы работа выполнялась синхронно. Я не хотел, чтобы та же работа выполнялась другим потоком (подход таймера), и реализация дополнительной блокировки для этого казалась пустой тратой.
Используйте подход, основанный на подходе System.Threading.WaitHandle.
using System.Threading;
private Thread _thread;
private ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
private ManualResetEvent _scheduleEvent = new ManualResetEvent(false);
private System.Timers.Timer _scheduleTimer = new System.Timers.Timer();
protected override void OnStart(string[] args)
{
// Configure the timer.
_scheduleTimer.AutoReset = false;
_scheduleTimer.Interval = 120000; // 2 minutes in milliseconds
_scheduleTimer.Elapsed += delegate { _scheduleEvent.Set(); }
// Create the thread using anonymous method.
_thread = new Thread( delegate() {
// Create the WaitHandle array.
WaitHandler[] handles = new WaitHandle[] {
_shutdownEvent,
_scheduleEvent
};
// Start the timer.
_scheduleTimer.Start();
// Wait for one of the events to occur.
while (!_shutdownEvent.WaitOne(0)) {
switch (WaitHandle.WaitAny(handles)) {
case 0: // Shutdown Event
break;
case 1: // Schedule Event
_scheduleTimer.Stop();
_scheduleEvent.Reset();
ThreadPool.QueueUserWorkItem(PerformScheduledWork, null);
break;
default:
_shutdownEvent.Set(); // should never occur
}
}
} );
_thread.IsBackground = true;
_thread.Start();
}
protected override void OnStop()
{
// Signal the thread to shutdown.
_shutdownEvent.Set();
// Give the thread 3 seconds to terminate.
if (!_thread.Join(3000)) {
_thread.Abort(); // not perferred, but the service is closing anyway
}
}
private void PerformScheduledWork(object state)
{
// Perform your work here, but be mindful of the _shutdownEvent in case
// the service is shutting down.
//
// Reschedule the work to be performed.
_scheduleTimer.Start();
}
У кого-то был аналогичный вопрос о суперпользователе. Вы можете установить инструмент, который отслеживает службы Windows. Что-то вроде Service Hawk поможет вам поддерживать работу служб или позволит вам запланировать автоматический перезапуск (возможно, в ночное время), чтобы служба работала без сбоев.