我正在尝试创建一个长时间运行的Windows服务,所以我需要在一个单独的线程上运行实际的worker类,以避免当我右键单击并选择start时“服务没有及时响应”错误在Windows服务管理器中。
worker类(“NotificationProcess”)有很多依赖项,我正在使用Autofac来满足这些要求。
我真的不确定如何为worker类设置Autofac。目前,当我在工人类的“执行”方法中使用它时,我收到错误告诉我DbContext已被处理。
我想我正在寻找如何编写一个Windows服务并为工作类使用一个新线程,其中依赖项由autofac满足。
我用谷歌搜索,找不到任何这方面的例子。
任何建议都很棒。
这是我到目前为止所得到的......
的Program.cs:
static class Program
{
static void Main()
{
using (var container = ServiceStarter.CreateAutoFacContainer())
{
var service = container.Resolve<NotificationService>();
if (Environment.UserInteractive)
{
service.Debug();
}
else
{
ServiceBase.Run(container.Resolve<NotificationService>());
}
}
服务类:
public partial class NotificationService : ServiceBase
{
private NotificationProcess _app;
readonly ILifetimeScope _lifetimeScope;
public NotificationService(ILifetimeScope lifetimeScope)
{
_lifetimeScope = lifetimeScope;
InitializeComponent();
}
protected override void OnStart(string[] args)
{
_app = _lifetimeScope.Resolve<NotificationProcess>();
_app.Start();
}
工人阶级:
public class NotificationProcess
{
private Thread _thread;
private readonly IBankService _bankService;
private readonly IRateService _rateService;
private readonly IEmailService _emailService;
private readonly IRateChangeSubscriberService _rateChangeSubscriberService;
private readonly IRateChangeNotificationService _rateChangeNotificationService;
private readonly ILogManager _logManager;
public NotificationProcess(IBankService bankService, ILogManager logManager, IRateService rateService, IEmailService emailService,
IRateChangeSubscriberService rateChangeSubscriberService, IRateChangeNotificationService rateChangeNotificationService)
{
_bankService = bankService;
_rateService = rateService;
_emailService = emailService;
_rateChangeSubscriberService = rateChangeSubscriberService;
_rateChangeNotificationService = rateChangeNotificationService;
_logManager = logManager;
}
public void Start()
{
_thread = new Thread(new ThreadStart(Execute));
_thread.Start();
}
public void Execute()
{
try
{
var rateChangeToNotify = _rateService.GetRateChangesForNotification();
foreach (var rateChange in rateChangeToNotify)
{
//do whatever business logic.....
}
}
}
答案 0 :(得分:3)
答案很简单:使用范围!您应该执行以下操作:
DbContext
),这些服务应在LifetimeScope生活方式的请求或操作期间生效。您通常会在Windows服务中使用计时器。每个'脉冲'都可以被视为一个请求。在您的情况下,这意味着您需要更改设计,因为NotificationService
已解决一次并且其依赖项在另一个线程上重用。这是依赖注入土地中的no-no。
这是另一种设计:
// This method is called on a background thread
// (possibly in a timely manner)
public void Run()
{
try
{
using (var scope = container.BeginLifetimeScope())
{
var service = scope.Resolve<NotificationService>();
service.Execute();
}
}
catch (Exception ex)
{
// IMPORTANT: log exception.
// Not logging an exception will leave us in the dark.
// Not catching the exception will kill our service
// because we run in a background thread.
}
}
使用生命周期范围可以为每个请求获得新的DbContext
,甚至可以让您并行运行请求(每个请求都有自己的DbContext
)。