c# – 高优先级的自定义命令Windows服务

c# – 高优先级的自定义命令Windows服务,第1张

概述我有一个部署在 Windows Server 2008中的Work Tracker WPF应用程序,此Tracker应用程序正在与(Tracker)Windows服务VIA WCF服务进行通信. 用户可以从Worker Tracker GUI应用程序创建任何工作条目/编辑/添加/删除/取消任何工作条目.在内部,它将向Windows服务发送请求. Windows服务将获取工作请求并在多线程中处理它. 我有一个部署在 Windows Server 2008中的Work Tracker WPF应用程序,此Tracker应用程序正在与(Tracker)windows服务VIA WCF服务进行通信.

用户可以从Worker Tracker GUI应用程序创建任何工作条目/编辑/添加/删除/取消任何工作条目.在内部,它将向windows服务发送请求. windows服务将获取工作请求并在多线程中处理它.每个workrequest条目实际上将在输出文件夹位置创建n个工作文件(基于工作优先级).

因此,每个工作请求将完成工作添加过程.

现在我的问题是如果我取消当前创建的工作条目.我想在RUNTIME中停止当前的windows服务工作.为工作创建输出文件的当前线程应该是StopPED.所有线程都应该被杀死.一旦用户请求取消,就应删除所有线程资源.

我的解决方法:

我使用windows Service On Custom Command方法在运行时将自定义值发送到windows服务.我在这里实现的是它正在处理当前工作或当前线程(即为收到的工作项创建输出文件).然后它将转到自定义命令以取消请求.

有没有办法让我们在获得自定义命令后停止工作项请求.

任何工作都非常感谢.

解决方法 摘要

您实际上是在为长时间运行的任务运行任务主机,并且能够取消这些任务.您的具体问题似乎想知道在.NET中实现它的最佳方法.您的架构很好,虽然您勇于推出自己的架构而不是使用现有的框架,但您之前没有提到过扩展架构.

我更喜欢使用TPL Task对象.它支持取消,并且易于轮询进度等.您只能在.NET 4以上使用它.

如果没有基本上为您设计整个作业托管引擎并了解您的.NET版本,则很难提供代码.我已经在下面详细描述了步骤,并参考了示例代码.

您使用windows服务OnCustomCommand的方法很好,如果您有客户端服务通信选项,您也可以使用消息服务(见下文).这对于您有许多客户端与中央作业服务进行通信并且作业服务与客户端不在同一台计算机上的情况更为合适.

在线程上运行和取消任务

在我们查看您的确切上下文之前,最好先查看MSDN – Asynchronous Programming Patterns.在线程上运行和取消作业有三种主要的.NET模式,我按优先顺序列出它们使用:

> TAP:Task-based Asynchronous Pattern

>基于Task,仅在.NET 4之后才可用
>从.NET 4开始运行和控制任何基于线程的活动的首选方法
>实施EAP要简单得多

> EAP:Event-based Asynchronous Pattern

>如果您没有.NET 4或更高版本,则唯一的选择.
>难以实施,但一旦你理解了它,你可以推出它,它是非常可靠的使用

> APM:Asynchronous Programming Model

>除非您维护旧代码或使用旧API,否则不再相关.
>即使使用.NET 1.1,您也可以实现EAP版本,因此我不会介绍您正在实施自己的解决方案

架构

想象一下这就像基于REST的服务.

>客户端提交作业,并返回作业的标识符
>作业引擎然后在准备就绪时接收作业,并开始运行它
>如果客户端不再需要该作业,则使用它的标识符删除作业

这样,客户端完全与作业引擎的工作隔离,并且可以随着时间的推移改进作业引擎.

工作引擎

方法如下:

>对于提交的任务,生成通用标识符(UID),以便您可以:

>确定正在运行的任务
>轮询结果
>如果需要,取消任务

>将UID返回给客户端
>使用该标识符对作业进行排队
>当你有资源时

>通过创建任务来运行作业
>将Task存储在字典中,将UID作为键

当客户端想要结果时,他们使用UID发送请求,并通过检查从字典中检索的任务来返回进度.如果任务完成,他们可以发送完成数据的请求,或者在您的情况下,只需去阅读已完成的文件.

当他们想要取消时,并通过在字典中找到它并告诉它取消来取消任务.

取消工作

在您的代码中,您需要定期检查取消令牌,看看是否应该停止运行代码(如果您使用的是TAP模式,请参阅How do I abort/cancel TPL Tasks?,或Albahari if you are using EAP).此时您将退出作业处理,如果设计得好,您的代码应该在需要时处理IDiposable,从内存中删除大字符串等.

取消的基本前提是您检查取消令牌:

>经过一段很长时间的工作(例如调用外部API)
>在您控制的循环(for,foreach,do或while)内,检查每次迭代
>在一长串顺序代码中,可能需要“一段时间”,您可以插入点以定期检查

您需要定义对取消作出反应的速度 – 对于windows服务,它应该在几毫秒内,最好是确保窗口在重新启动或停止服务时没有问题.

有些人用线程完成整个过程,并通过终止线程 – 这很难看,不再推荐了.

可靠性

您需要问:如果服务器重新启动,windows服务崩溃或发生任何其他异常导致您丢失不完整的作业会发生什么?在这种情况下,您可能需要一个可靠的队列体系结构,以便能够重新启动作业或重建尚未启动的作业队列.

如果您不想扩展,这很简单 – 使用windows服务存储作业信息的本地数据库.

>提交作业后,将其详细信息记录在数据库中
>启动作业时,将其记录在数据库中的作业记录中
>当客户端收集作业时,将其标记为数据库中的延迟垃圾回收,然后在设定的时间(1小时,1天……)后将其删除
>如果您的服务重新启动并且有“正在进行的作业”,则将其重新排队,然后再次启动您的作业引擎.

如果您确实想扩展,或者您的客户端在许多计算机上,并且您有一个或多个服务器的作业引擎“场”,那么请查看使用消息队列而不是使用OnCustomCommand直接通信.

消息队列有多种好处.它们将允许您可靠地将作业提交到中央队列,然后许多工作人员可以接收并处理这些作业,并将您的客户端和服务器分离,以便您可以扩展您的作业运行服务.它们用于确保以高度分离的方式可靠地提交和处理作业,这可以在本地或全局工作,但始终可靠,您甚至可以将其与在云工作者上运行windows服务相结合,您可以动态扩展.

技术的例子是MSMQ(如果你想维护自己的,或者必须留在你自己的防火墙内),或者Windows Azure Service Bus (WASB)–这很便宜,已经为你完成了.在任何一种情况下,您都希望使用Patterns and Best Practices for Enterprise Integration.在WASB的情况下,有many (MSDN),many (MSDN samples for BrokeredMessaging etc.),many (new Task-based API)开发人员资源,以及NuGet packages供您使用

总结

以上是内存溢出为你收集整理的c# – 高优先级的自定义命令Windows服务全部内容,希望文章能够帮你解决c# – 高优先级的自定义命令Windows服务所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1218159.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存