gpt4 book ai didi

c# - 如何使用线程使 Windows 服务长期运行

转载 作者:行者123 更新时间:2023-11-30 14:42:07 24 4
gpt4 key购买 nike

我有一个 win 服务托管一些我需要保持长期运行的工作流(一个 WorkflowApplication 和一个 WorkflowServiceHost)。因为 OnStart() 要求它完成并返回到操作系统,所以我有一个 main 方法在线程池中的另一个线程上触发。我的 Onstart() 主要是这样的

protected override void OnStart(string[] args)
{
eventLog.WriteEntry("Service starting...");
ThreadPool.QueueUserWorkItem(new WaitCallback(ServiceMainThread));
Thread.Sleep(100);
eventLogCms.WriteEntry("Service Started.");
}

ServiceMainThread() 是我的工作流执行和核心功能实现的方法。当我在我的 Windows 7 机器上启动该服务时,它会运行,然后在大约 8 分钟后停止运行。在 Win Server 2008 上,线程从不执行。

所以我认为我错误地实现了线程,ServiceMainThread 有点不稳定。我对可以改进的地方或任何方向的建议持开放态度,因为我是 .Net 中线程的新手。 ServiceMainThread 中的基本线程代码编码如下:

private void ServiceMainThread(object state)
{
// .. execute workflows ..
eventLog.WriteEntry("Workflows executed.");

while(alive)
{
Thread.Sleep(1);
// ... check workflow states and ensure they're still executing ...
}

// .. halt workflow executions and perform persist operations if necessary ..
eventLog.WriteEntry("Workflows halted.");
}

为了完整说明,这里是我的 OnStop() 实现:

protected override void OnStop()
{
alive = false;
this.haltEvent.WaitOne(); // haltEvent is of type ManualResetEvent
}

有什么明显的我可以更改以使我的工作流长期保持在执行状态吗? while 循环似乎有点太老套了(更不用说我不喜欢将线程延迟任何时间)而且我相信可能有更好的解决方案。

使用线程而不是线程池确实可以启动,但它似乎允许工作流在执行开始前运行 2 分钟,现在停止已中断,但我认为我可以更正 OnStop()。当我这样做时,我将 ServiceMainThread() 中的 while 循环设置为一个空 block ,这样它就不会阻塞正在执行工作流的线程。

更新:我在事件日志中从 .Net 得到这个异常:

Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.NullReferenceException
Stack:
at Ptm.ServiceMainThread()
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Threading.ThreadHelper.ThreadStart()

Server 2008 是 64 位的,这与我的问题有关吗?

最佳答案

首先,对于一个长时间运行的线程,创建自己的Thread对象并启动它;不要使用 ThreadPool。线程池专为小型、相对短期的操作而设计。

其次,有几种方法可以让您的线程保持事件状态。最基本的是您尝试过的,这是一个 while 循环,最后有一个 sleep (或其他阻塞)调用。这是最基本的,但不一定是“最好的”。还有其他选项,例如可以从其他应用程序访问的命名 WaitHandle 对象,可以允许更确定的代码执行和更少的 wake-check-sleep 迭代。

但是,如果您不能(或不想)修改其他进程以支持将特定事件通知您的服务,那么您所拥有的基本上是正确的。但是,我鼓励选择更合理的 Sleep 时间;您真的需要每毫秒检查一次吗?

关于c# - 如何使用线程使 Windows 服务长期运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3344633/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com