Jos*_*osh 22 c# multithreading windows-services backgroundworker
我正在编写一个Windows服务,一旦启动就会每X小时运行一次.它完成的过程相当密集,所以我想使用后台工作程序.我正在使用设置文件来存储运行和上次运行服务之间的小时数.
我不确定最好的方法 - 也就是说,我希望服务尽可能少地使用资源,当它运行时,它需要在后台工作程序中运行,报告它做了什么,然后回到空闲模式.
我考虑过使用2名背景工作者.第一个worker是服务的私有局部变量,运行如下:
while (true)
{
//create new background worker and run
Thread.Sleep(Settings.Default.SleepTimeHours * 3600000);
}
Run Code Online (Sandbox Code Playgroud)
使用在循环的每次迭代中创建的子工作程序,并在完成时销毁.为了支持取消,我想我必须在服务中有第二个工作者的本地实例,但如果当前进程没有运行,它将为null.当辅助工作程序完成时,它将发送我的报告,在设置文件中设置上次运行时间,然后处理该工作程序并将引用设置为null.
我想知道是否有更好的方法来做这个或最好的做法.
谢谢
mar*_*c_s 15
这不是一个好主意,因为你在整个"SleepTimeHours"期间锁定了你的线程,在此期间你甚至无法停止服务.
您可以制作此服务,使其睡眠时间为5秒,然后检查是否需要重新开始工作,如果没有,再睡5秒钟(如果您需要停止,则可以提供必要的响应)服务).
或者:您可能最好只编写一个可以使用Windows"计划任务"功能进行安排的控制台应用程序,以便每x小时运行一次.这样,如果您的应用没有做任何事情,您将不会阻止或使用任何系统资源......
渣
怎么样更像这样的东西:
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.
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用基于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();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
46149 次 |
| 最近记录: |