C# 如何使用异步编写具有长时间运行功能的Windows服务?

C# 如何使用异步编写具有长时间运行功能的Windows服务?,c#,.net,windows,service,C#,.net,Windows,Service,我的第一次非异步尝试是使用计时器每15秒调用一次进程。这很快创建了多个正在运行的进程,这些进程在数据库上启动了竞争条件,因为函数\u myApp.ProcessQueue()可能需要5-10分钟才能运行。这实际上锁定了数据库,因为它试图读取和写入相同的行。如果我增加计时器,它将防止潜在的比赛条件,但我不认为这是一个非常务实的方式来进行这项服务 protected override void OnStart(string[] args) { _log.Info($"Service is s

我的第一次非异步尝试是使用计时器每15秒调用一次进程。这很快创建了多个正在运行的进程,这些进程在数据库上启动了竞争条件,因为函数
\u myApp.ProcessQueue()可能需要5-10分钟才能运行。这实际上锁定了数据库,因为它试图读取和写入相同的行。如果我增加计时器,它将防止潜在的比赛条件,但我不认为这是一个非常务实的方式来进行这项服务

protected override void OnStart(string[] args)
{
    _log.Info($"Service is started at {DateTime.Now}.");
    timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
    timer.Interval = 15000;
    timer.Enabled = true;
}

private void OnElapsedTime(object source, ElapsedEventArgs e)
{
    int recCount = _dbHandler.CheckQueueCount();

    if (recCount > 0)
    {
        _log.Info($"Found {recCount} records in the queue.");

        try
        {
            _myApp.ProcessQueue();
        }
        catch (Exception exception)
        {
            _log.Error(exception);                    
            Stop();
        }
    }
}
我正在考虑如何使用异步函数,但我在编写时遇到了困难,因为我以前没有使用.Net的异步功能。

使用
OnStart()
在另一个线程中初始化运行程序(
Task.Run()
或者如果必须调整某些参数
Task.Factory.Start())
)在短时间内正确返回该方法

如果我理解正确的话,你一次只想处理一份工作,然后再处理下一份工作,对吗

我的例子包括总是等待额外的15秒。如果你不想这样,你必须稍微调整一下代码

没有异步/等待

要使循环与作业处理同步,可以在另一个线程(见上文)中启动作业,并使用
AutoResetEvent
。在循环中,您将使用autoResetEvent.WaitOne()等待,一旦您的工作完成,您就可以使用autoResetEvent.Set()发出信号,让另一个线程继续

使用适当的方法等待15秒,如
Thread.Sleep()

使用异步/等待 这要容易得多,你只需要等待你的任务电话

await Task.Run(() => MyJobMethod(argA, argB, ...));
await Task.Delay(15000);

我建议你好好评价一下!这看起来很有希望。谢谢你的推荐。如果你选择Windows服务路线,一定要看看TopShelf。它负责注册/注销、挂接到许多DI容器、日志框架等。我们有一个古老但功能强大的自定义任务管理器,可以监视windows服务并在它们停止时发出警报。它不是超级健壮,但功能强大。我将与团队讨论如何过渡到使用现成的产品,如TopShelf或Hangfire。