重复执行一个代码块而不超时.windows服务

本文关键字:超时 服务 windows 代码 一个 执行 复执 | 更新日期: 2023-09-27 18:11:37

我写了一个简单的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主体?

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语句,以便我能够在isStopped为真时调用break ?

重复执行一个代码块而不超时.windows服务

您不必处理低级线程和同步原语API。考虑使用任务并行库(TPL)。使用TPL取消框架很容易实现OnStop:

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绑定的工作项。

使用线程,您可以使用以下代码实现您的需求:

internal class ServiceModel {
    private Thread workerThread;
    private object syncLock = new object();
    private bool stop = false;
    public void Start() {
        this.workerThread = new Thread(this.Process);
        this.workerThread.Start();
    }
    public void Stop() {
            lock(syncLock) stop = true;
            this.workerThread.Join(30000);
    }
    public void Process() {
        while(true){
           //your stuff here.
          lock(syncLock)
          {
             if(stop)
                 break;
          }
          Thread.Sleep(30000); 
        }
    }
}