[英]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上的任务。 有许多不同的延续选项可用于任务。 探索适合您需求的产品。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.