c# - 重复执行一段代码而没有超时。窗口服务

标签 c# .net multithreading

我编写了一个简单的 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 放在哪里?声明,以便我可以调用breakisStopped是真的?

最佳答案

您不必处理低级线程和同步原语 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/

相关文章:

.net - 在 VB.NET 中使用 LINQ 的 ForEach 和匿名方法

.net - Chirpy 不会在文件后面创建代码吗?

在c中为linux创建一个新线程?

c# - 如何部署我的 C# 项目?

c# - 使用 EF 将数据插入 SQL 数据库

c# - C# 中的访问级别修饰符与程序集加载

java - 内存不一致与线程交错有何不同?

c++ - 使用 boost::thread 将 const 指针参数传递给函数

c# - ASP.NET Web 应用程序无法使用自定义 Bootstrap 正确显示内容

c# - 如何将工具提示添加到 winform 上的用户定义文本框