【问题标题】:Windows service and design patternWindows 服务和设计模式
【发布时间】:2014-01-13 04:01:27
【问题描述】:

我有一个 Windows 服务来执行后台进程。此 Windows 服务将与 asp.net 网站交互。功能如下。

在我的网站上有 3 个操作。用户可以选择任务(假设有三个按钮)。然后它会调用windows服务。其余操作由 Windows 服务执行。用户可以从网站注销,但它将在后台运行服务。一旦完成,它将在数据库中进行相应的更改。 我需要知道是否可以将任何设计模式应用于 Windows 服务(工厂、抽象工厂等)。我已经阅读了不同的设计模式,但我对如何将其应用于项目感到非常困惑。目前,我正在 Windows 服务的“OnStart”和“OnStop”事件中编写整个代码。请指导我。

谢谢。

【问题讨论】:

  • 您至少需要通过在 OnStart 方法中创建一些正在运行的线程来开始。理想情况下,OnStart 方法需要立即完成。否则,当您启动该服务时,它将与“正在启动”消息一起挂起,直到超时。听起来您可能想查看一些基本的服务教程并发布您遇到的具体问题。 This 是定时器的基本用法。
  • 非常感谢您的回复。这真的很有用。目前我正在创建多个服务实例来处理登录到网站的多个用户。现在我认为不是创建多个服务实例,我可以为另一个用户的请求创建一个新线程..rt?(一个服务和多个线程)我还可以限制要创建的新线程的数量。这是一个正确的方法吗?
  • 那么设计模式呢?我的服务逻辑包含一些数据库操作和一些带有只读数组的静态类。那里的设计模式有什么特定的作用吗?我对它的用法有点困惑。--> 谢谢。

标签: design-patterns windows-services


【解决方案1】:

我安装多个服务实例的唯一一次是用于多个环境,例如开发、测试和生产。否则,它应该保留在同一个服务中,假设所有代码在逻辑上都是相关的。

至于设计模式,对于我创建的大多数服务,我一直遵循一个简单的“模式”。我鼓励回答,因为我自己不知道这是否是一个好的模式。它基本上涉及创建一个立即启动的主线程,以及基于需要做什么的子线程。对于您的情况,以下可能是用户处理器的简单服务布局。

服务类:

public partial class Service : ServiceBase
{
    private Processor _processor;

    public Service() { InitializeComponent(); }

    protected override void OnStart(string[] args)
    {
        _processor = new Processor();
        new System.Threading.Thread(_processor.Run).Start();
    }

    protected override void OnStop()
    {
        _processor.Stop();
    }
}

处理器:

public class Processor
{        
    private bool _continue;
    private List<UserProcessor> _userProcessors; // List of users being processed.

    public void Run()
    {
        _continue = true;
        while (_continue)
        {
            var users = getUsersToProcess();
            foreach (User user in users)
            {
                if (_userProcessors.Any(u => u.UserId == user.UserId) == false)
                {
                    // Start a new processor for the user since it wasn't found.
                    var processor = new UserProcessor(user);
                    new System.Threading.Thread(processor.Run).Start();
                    _userProcessors.Add(processor);
                }
            }

            System.Threading.Thread.Sleep(1000);
        }
    }

    public void Stop()
    {
        _continue = false;

        foreach (var processer in _userProcessors)
            processer.Stop();
    }

    private List<User> getUsersToProcess() { throw new NotImplementedException(); }
}

当然,UserProcessor 的设置几乎与 Processor 相同,但在 while 循环中使用了不同的代码。这是您进行数据库交互的地方,但我会让您弄清楚这部分。

【讨论】:

  • @Dev,如果您有一个工作示例需要评论,您也可以查看Code Review
  • @making3,您是否错过了在调用启动其 Run 任务后将 UserProcessor 添加到 _userProcessors 集合的代码?
  • @samneric,你说得对,很好。它会编译,但 Stop() 在那个时候不能正常工作,因为 _userProcessors 不会被填充。
  • 另外,我开始使用代码 - 很好,谢谢! - 我刚刚从 Threading.Thread.Start 切换到了当代方面的 Task.Start :)
猜你喜欢
  • 1970-01-01
  • 2012-08-21
  • 1970-01-01
  • 1970-01-01
  • 2012-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多