简体   繁体   English

防止 windows 服务器暂停我的进程

[英]Prevent windows server from suspending my process

I've developed a program (winforms application, not a service) in C# that runs on a windows server.我在 C# 中开发了一个程序(winforms 应用程序,而不是服务),该程序在 windows 服务器上运行。

The program starts multiple times based on requests from outside the server.该程序根据来自服务器外部的请求多次启动。

From time to time I see that the program is "Suspended" for an unknown reason.我不时看到该程序由于未知原因而“暂停”。 I think it is related to a lack of resources, but not sure.认为这与缺乏资源有关,但不确定。 在此处输入图像描述

How can I prevent windows from suspending my program?如何防止 windows 暂停我的程序?

Update To be clear, I know that the program crash and it is OK.更新要清楚,我知道程序崩溃并且没关系。 What I'm asking is not how to improve performance \ prevent the crash, but how to remove the process from the process list \ prevent this suspended status?我要问的不是如何提高性能\防止崩溃,而是如何从进程列表中删除进程\防止这种挂起状态?

Depends in your hardware/software configuration , it's hard to know where is your bottleneck.取决于您的硬件/软件配置,很难知道您的瓶颈在哪里。

I recommend instead to do Multi-thread/task app where you're able to control threads and asign priority, resources, stop, resume, abort, etc...我建议改为使用多线程/任务应用程序,您可以在其中控制线程并分配优先级、资源、停止、恢复、中止等......

use on command console to start and check if happends the same but with the parameter high:在命令控制台上使用启动并检查是否发生相同但参数高:

start /HIGH <ProgramPath>

Read more how to change priority on executables阅读更多如何更改可执行文件的优先级

Task Scheduler on windows servers MSDN -> Priority windows 服务器上的任务计划程序 MSDN -> 优先级

(It's only an opinion, start digging about others solutions.) (这只是一个意见,开始挖掘其他解决方案。)

You must set the ServiceBase.CanPauseAndContinue Property to False in the constructor of the service before it is started.在服务启动之前,您必须在服务的构造函数中将ServiceBase.CanPauseAndContinue属性设置为False

NOTE the side effect is:注意副作用是:

If CanPauseAndContinue is false, the SCM will not pass Pause or Continue requests to the service, so the OnPause and OnContinue methods will not be called even if they are implemented.如果 CanPauseAndContinue 为 false,则 SCM 不会将 Pause 或 Continue 请求传递给服务,因此即使实现了 OnPause 和 OnContinue 方法也不会被调用。 In the SCM, the Pause and Continue controls are disabled when CanPauseAndContinue is false.在 SCM 中,当 CanPauseAndContinue 为 false 时,Pause 和 Continue 控件被禁用。

For more information see this Microsoft Doc有关详细信息,请参阅此Microsoft Doc

There are multiple methods of keeping an app awake.有多种方法可以让应用保持唤醒状态。

One method would be to request a deferral and then only mark that deferral complete when you are done.一种方法是请求延期,然后仅在完成后标记延期完成。

First you need a deferral object that will remain in scope of your process首先,您需要延迟 object 将保留在您的流程的 scope 中

SuspendingDeferral deferral

Then you need to override OnSuspending然后你需要覆盖OnSuspending

async protected void OnSuspending(object sender, SuspendingEventArgs args)
{
    deferral = args.SuspendingOperation.GetDeferral();
    await SuspensionManager.SaveAsync();
}

Then you need to mark the deferral complete when your process is done doing whatever it was doing然后,当您的流程完成时,您需要将延迟标记为完成

    if (deferral is not null) { deferral.Complete(); }

Full details can be found in the Microsoft docs完整的详细信息可以在Microsoft 文档中找到

For discussion of other methods see this thread: How to Disable UWP App Suspension?有关其他方法的讨论,请参阅此线程: 如何禁用 UWP 应用程序暂停?

Technically the process is suspended but if you look at the memory consumption of 32K you can tell it was not suspended.从技术上讲,该过程已暂停,但如果您查看 32K 的 memory 消耗,您可以看出它没有暂停。 Your process did crash with an unhandled exception which in turn triggers Windows Error Reporting to take a memory dump.您的进程确实因未处理的异常而崩溃,这又会触发 Windows 错误报告以进行 memory 转储。

This involves some kernel magic which keeps a process handle in the kernel (System process) alive.这涉及一些 kernel 魔术,它使 kernel(系统进程)中的进程句柄保持活动状态。 It is not a big deal or memory leak since the process did already terminate.这不是什么大问题或 memory 泄漏,因为该过程已经终止。 Only the PEB (Process Environment Block) the 32K which includes mostly command line, loaded dlls and environment variables are still there.只有PEB(进程环境块)32K,主要包括命令行,加载的dll和环境变量仍然存在。

I would not worry about suspended processes but why your process did crash with an unhandled exception.我不会担心挂起的进程,但为什么您的进程会因未处理的异常而崩溃。 This could even be a feature to make programers aware that their process did crash by looking at a looong list of suspended processes in Task Manager;-).这甚至可以是一个功能,让程序员通过查看任务管理器中挂起的进程的冗长列表来意识到他们的进程确实崩溃了;-)。

Since it is a .NET Application you will find a generic error messages that a process did crash in the Application event log and a .NET Runtime logged error message with more exception details.由于它是一个 .NET 应用程序,您会在应用程序事件日志中找到一个进程确实崩溃的一般错误消息,以及一个 .NET 运行时记录的错误消息,其中包含更多异常详细信息。 在此处输入图像描述

Perhaps that is already enough to keep you going to fix your issue.也许这已经足以让你继续解决你的问题。 If not you can configure WER to create a full memory dump via a registry setting ( https://docs.microsoft.com/en-us/windows/win32/wer/collecting-user-mode-dumps ).如果不是,您可以配置 WER 以通过注册表设置 ( https://docs.microsoft.com/en-us/windows/win32/wer/collecting-user-mode-dumps ) 创建完整的 memory 转储。 Now you have for each "suspended" process a full memory dump you can load into Visual Studio to look further what was the issue.现在,您为每个“暂停”进程提供了一个完整的 memory 转储,您可以将其加载到 Visual Studio 中以进一步查看问题所在。

To further check who holds your process handle still open you can use handle eg ProcessHacker (the better Process Explorer) https://processhacker.sourceforge.io/nightly.php要进一步检查谁持有您的进程句柄仍处于打开状态,您可以使用句柄,例如 ProcessHacker(更好的 Process Explorer) https://processhacker.sourceforge.io/nightly.php

在此处输入图像描述

If something else is happening you can see with this tool who is holding any outstanding handles to your process open.如果发生了其他事情,您可以使用此工具查看谁持有您的进程的任何未完成句柄打开。 But I strongly suspect it is the Windows Kernel.但我强烈怀疑它是 Windows Kernel。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM