将 Windows 服务实现为“工作者”的最佳方式

Posted

技术标签:

【中文标题】将 Windows 服务实现为“工作者”的最佳方式【英文标题】:Best way to implement windows service as "worker" 【发布时间】:2015-07-08 08:35:39 【问题描述】:

我有一个允许用户启动程序的 ASP .NET 页面。这些程序和参数存储在数据库中,然后 Windows 服务执行这些程序。 这些程序是实现我的 IPlugin 接口的 dll,所以我可以在运行时添加它们(dll 在运行时加载,因此我可以在运行时添加它们而无需编译或重新启动服务)。

我创建了 ASP .NET 页面、10 多个程序(插件)和 windows 服务。一切运行良好,但我认为 windows 服务的实现很糟糕。

windows 服务会定期查询数据库并在获得新条目时执行所需的程序。该服务可以并行运行多个程序(目前为 3 个程序)。

目前我的服务方法是这样的:

 while (Alive)
        
                // gets all running processes from the database
                Processes = Proc.GetRunningProcs();

                // if there are less than 3 processes running and
                // a process is in queue
                if (ReadyToRun())
                
                    // get next program from queue, sets the status to 
                    // runnig and update the entry in the database
                    Proc.ProcData proc = GetNextProc();
                    proc.Status = Proc.ProcStatus.Running;
                    Proc.Update(proc);

                    // create a new thread and execute the program
                    Thread t = new Thread(new ParameterizedThreadStart(ExecuteProc));
                    t.IsBackground = true;
                    t.Start(proc);
                

            Thread.Sleep(1000);
        

我有一个方法可以在数据库中查询状态为“正在取消”的条目(如果用户取消程序,状态将设置为“正在取消”)并执行 Thread.Abort()。

有更好的做法吗?比如使用带有取消机制的任务或者整个概念(将进程存储在数据库中(程序名称、参数、状态......并定期查询这些信息)是错误的?

【问题讨论】:

使用 .Net 中已经内置的 Task 对象,并使用 CancellationTokens。 Task class 不能被有效地覆盖(我忘记了原因),但如果你足够聪明,你可以使用复合模式(我会给你一个例子,但我手头没有代码)。 其实我找到了-try this, 【参考方案1】:

作为替代方案,您可以使用一些现有的库来满足您的目的,例如 Quartz.NET http://www.quartz-scheduler.net/。它关心工作持久性、工作调度和许多其他事情。您必须做的就是创建一个适配器并将其放入 Windows 服务中。

【讨论】:

以上是关于将 Windows 服务实现为“工作者”的最佳方式的主要内容,如果未能解决你的问题,请参考以下文章

c#从Windows服务启动应用程序的最佳方式

在 Windows 服务和表单应用程序之间发送和接收消息的最佳方式

为客户端-服务器通信构建 TCP/IP 服务器的最佳方式?

桌面应用程序和 Windows 服务之间通信的最佳方式

在 Windows 上使用 python 实现 WebSocket 项目的最佳方式

以编程方式生成工作者角色的新实例