繁体   English   中英

Windows服务中的并行任务

[英]Parallel Tasks In Windows Services

我有一个Windows服务,它启动计时器上的功能。 该函数在数据库中查询新记录,然后为找到的每个新记录调用Web服务。

现在要求此服务在每个间隔为多个数据库执行此操作。

该服务目前看起来像这样:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.ServiceProcess;

namespace MiManager.TicketLogger {

  public partial class TicketLogger : ServiceBase {

    private TicketLoggerSettings _settings;
    private List<DbConnectionSettings> _connections;

    public TicketLogger() {
      InitializeComponent();
    }

    protected override void OnStart(string[] args) {

      var helpers = new MiManager.TicketLogger.Helpers();
      _settings = helpers.GetTicketLoggerSettings();
      _connections = helpers.GetDbConnectionSettings();

      if (_settings.LogVerbose == true) evlgTicketLogger.WriteEntry("Registry entries obtained", EventLogEntryType.Information, 100);
      tmrTicketLogger.Interval = _settings.ServiceInterval;
      tmrTicketLogger.Elapsed += new System.Timers.ElapsedEventHandler(TimerElapsed);
      tmrTicketLogger.Enabled = true;
      tmrTicketLogger.Start();
    }

    protected override void OnStop() {
      tmrTicketLogger.Stop();
      tmrTicketLogger.Enabled = false;
    }

    private void TimerElapsed(Object sender, System.Timers.ElapsedEventArgs e) {
      try {
        tmrTicketLogger.Stop();

        Core core = new MiManager.TicketLogger.Core();
        List<Message> messages = core.LogTickets(_settings);
        foreach (var message in messages) {
          evlgTicketLogger.WriteEntry(message.Text, message.EntryType, message.ErrorCode);
        }
        if (_settings.LogVerbose == true) {
          evlgTicketLogger.WriteEntry("Ticket logging complete", EventLogEntryType.Information, 101);
        }
      }
      catch (Exception ex) {
        evlgTicketLogger.WriteEntry(ex.ToString(), EventLogEntryType.Error, 400);
      }
      finally {
        tmrTicketLogger.Start();
      }
    }

  }

}

现在我需要调整服务以获取多个连接字符串,并在每个数据库连接的TimerElapsed函数中调用LogTickets函数。

目前推荐的在Windows服务中执行此操作的方法是什么?

在多年前的一个项目中,我手动为我想要处理的每个连接创建了一个新线程,但我相信现在有更好的方法吗?

它是Async / Await的一个很好的用例吗? 如果我这样做,Core类中的所有方法都必须是异步的吗?

使用Parallel.ForEach这样的东西会更好吗?

在服务器端, async方法为您提供可伸缩性。 但是,听起来您的服务不需要扩展太多,因此async不会给您带来任何好处。

使用Parallel.ForEach这样的东西会更好吗?

如果您现有的代码是同步的(并且您不需要async会给您的可伸缩性),那就没关系。 如果将所有内容更改为async ,那么您的服务将会消耗更少的资源(并且可能会稍微快一些) - 但这需要对(AFAICS)进行相当多的代码更改,但收效甚微。

如果你想在Win32服务中探索async代码,我建议使用我的AsyncContextThread类型创建一个主线程。 只要您的async代码正确异步(例如,使用EF6进行异步数据库调用 ,使用HttpClient进行异步Web调用 ),那么您应该只需要一个线程。

这在很大程度上取决于您的解决方案的复杂性需求,您希望如何处理数据以及您当前的.NET框架版本是什么,因为有很多方法可以做到这一点。

您可以执行以下操作:HandleConnection是您处理连接的函数:

var parallelTask = Task.Factory.StartNew(() => Parallel.ForEach(_connections, connection => HandleConnection(connection)));

我建议使用几分钟来阅读并行性,.NET 4.5中的新异步/等待功能以及MSDN上的任务。 有许多不同的延续选项可用于任务。 探索适合您需求的产品。

数据并行

使用Async和Await进行异步编程

任务工厂

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM