【发布时间】:2015-09-03 19:46:50
【问题描述】:
我设置了一个 Windows 服务来管理自定义 .Net 任务。组织是:
-Windows 服务监控计划并根据需要启动工作程序 .exe。
-Worker .exe(轻量级 Winform 应用程序)使用命令行参数拉出 DLL(插件)并运行一些代码。
这几个月来一直运行良好。我最近将它迁移到 Server 2012(从 2008 IIRC)——这可能无关,但很难说。迁移后一段时间以来,我遇到了一个问题,即 worker .exe 在被 process.start() 调用后“启动”,但没有到达我的代码。没有错误或任何东西,它似乎只是在应用加载期间冻结。
启动它的服务代码相当标准。
// Create a temp folder and copy the executable to it
// (so the source exe isn't always in use and can be swapped out)
Process p = new Process();
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = Path.Combine(temp.Path, Path.GetFileName(ExecutablePath));
psi.Arguments = CommandLineArgs.ConcatenateList(" ");
psi.UseShellExecute = false;
psi.RedirectStandardError = true;
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.CreateNoWindow = true;
psi.ErrorDialog = false;
psi.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo = psi;
p.Start();
// read standard output if necessary, kill and reschedule if appears to be frozen, etc.
此时,worker 可执行文件启动 - 它在任务管理器中看起来很正常。唯一让我知道出现问题的是内存消耗 - 在正常情况下,工作人员在启动期间会达到 5MB 左右并增长以反映任务,但当进程冻结时,它只会达到 2MB 左右并停止。
为了证明它不是我在工作程序中的任何代码,我在第一行添加了对日志记录函数的调用,但从未见过日志。
没有错误消息,而且 - 真正奇怪的一点 - 这不是一个一致的问题。现在冻结的完全相同的呼叫将在 30 秒后正常运行。问题发生时似乎也没有任何真正的模式 - 我看到的最接近的事情是它偶尔会同时发生在多个任务上(例如,它可能会影响在问题发生时开始的所有任务发生在任何任务中)。
我有它,服务可以自动检测它并适当地处理它,所以这不是一个紧急问题,但如果一个原因或解决方案对任何人来说都很突出,我仍然想解决这个问题。
worker 的初始化代码只是一个标准的 win forms 启动,我的东西开始在 form_load 中被调用。
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// Do Stuff - never gets hit when the freeze happens.
}
编辑:每个 cmets,设置服务以使用它在看到挂起进程时创建的日志条目记录小型转储。明天会检查它,看看它会发生什么。
2015 年 9 月 4 日编辑:小型转储信息:
minidump 显示代码在 static void main 的退出 } 处停止/卡住,即:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
} // <------ This is where the main thread is frozen.
否则一切似乎都很好。
我将做一些研究并尝试对工人进行一些更改以防万一。
编辑 2015 年 9 月 4 日 #2: 调整了工人启动,它似乎正在工作。它的要点是删除表单引用并仅使用应用程序上下文(例如codeproject sample)
我用任务请求敲打了系统,它没有任何问题。我会让它在周末运行作为测试,并在周二进行状态更新。 仍然很好奇为什么它会随着表单加载而随机中断。
现在的代码:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new AppContext());
}
}
class AppContext : ApplicationContext
{
public AppContext()
{
// Do Stuff
}
}
【问题讨论】:
-
我认为您应该发布该工作程序 .exe 的初始化代码。
-
已更新 - 在 form_load 之前,它只是标准的(VS 生成的)init 东西,此时我的东西(通常)会启动。将日志调用作为 form_load 的第一行是我想出来的没有达到那个点。
-
您是否尝试过在进程挂起时将其转储并加载到 VS/WinDBG 以找出它挂起的位置?
-
您是否尝试过独立运行该 WinForms 程序以查看它是否启动?我认为您的表单定义本身有问题,导致无法对其进行初始化。
-
还没有——我通常不需要进行远程调试,所以我不太确定所有可用的工具。编辑因为 shift+enter vs enter:我将对服务进行一些调整,下次发生时试一试。
标签: c# .net windows-services windows-server-2012