我编写了一个简单的 Windows 服务,这是它的骨架:
internal class ServiceModel {
private Thread workerThread;
private AutoResetEvent finishedEvent;
private Int32 timeout = 60000*15;
public void Start() {
this.workerThread = new Thread(this.Process);
this.finishedEvent = new AutoResetEvent(false);
this.workerThread.Start();
}
public void Stop() {
this.finishedEvent.Set();
this.workerThread.Join(30000);
}
public void Process() {
while(!this.finishedEvent.WaitOne(timeout)) {
// run things here
}
}
}
第一件事
我无法理解的第一件事是服务在运行前等待一个超时。将重写
new AutoResetEvent(false);
至new AutoResetEvent(true);
导致服务无需等待即可启动?第二件事
由于某些内部原因(从外部服务器/服务请求数据、异常处理),有时等待固定的 15..30 分钟超时是不够的。
如何在没有固定超时的情况下重写它以使其工作?
我需要删除
AutoResetEvent
实例并运行Process
body 在无限循环中?public void Process() {
while(true) {
// run things here
}
}
编辑。 try catch /锁定
在
Process
方法有一个全局try-catch
堵塞:public void Process() {
do {
try {
// processing goes here
}
catch(Exception ex) {
Logger.Log.Warn(ex); // or Log.Fatal(ex)...
}
}
while(true);
}
如果我使用同步对象,我应该把
lock
放在哪里?声明,以便我可以调用break
当isStopped
是真的?
最佳答案
您不必处理低级线程和同步原语 API。考虑使用 Task Parallel Library (TPL) .很容易实现OnStop
使用 TPL cancellation framework :
using System.ServiceProcess;
using System.Threading;
using System.Threading.Tasks;
namespace WindowsService1
{
public partial class Service1 : ServiceBase
{
CancellationTokenSource _mainCts;
Task _mainTask;
public Service1()
{
InitializeComponent();
}
async Task MainTaskAsync(CancellationToken token)
{
while (true)
{
token.ThrowIfCancellationRequested();
// ...
await DoPollingAsync(token);
// ...
}
}
protected override void OnStart(string[] args)
{
_mainCts = new CancellationTokenSource();
_mainTask = MainTaskAsync(_mainCts.Token);
}
protected override void OnStop()
{
_mainCts.Cancel();
try
{
_mainTask.Wait();
}
catch
{
if (!_mainTask.IsCanceled)
throw;
}
}
}
}
内部
MainTaskAsync
您可以使用 Task.Run
对于任何受 CPU 限制的工作项。
关于c# - 重复执行一段代码而没有超时。窗口服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24604443/