问题描述
我有一个Windows服务设置管理自定义.NET任务。组织是:
-Windows服务监测的时间表,并开始根据需要工人.exe文件。
-Worker .EXE(轻量级winform应用程序)使用命令行参数来拉了一个DLL(插件),然后运行一些code。
这一直运作良好几个月。我最近迁移到服务器2012(从2008年IIRC) - 这可能是不相关的,但很难说。由于迁移了一段时间后,我遇到了一个问题,即工人.EXE开始被称为用的Process.Start()之后,但没有达到我的code。没有错误或任何东西,它只是似乎应用程序加载过程中冻结。
服务code启动是相当标准。
//创建一个临时文件夹和可执行文件复制到其中
//(因此源的exe并不总是在使用中,并且可以被换出)
进程p =新的Process();
的ProcessStartInfo磅=新的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();
如果需要的话//读取标准输出,杀死并重新安排,如果出现被冻结,等等。
在这一点上,工人可执行启动 - 这似乎大多正常,在任务管理器。唯一的提示我了的东西走了错的是内存消耗 - 正常情况下围绕5MB工人击中发射期间增长反映了任务,但在这个过程冻结只达到约2MB并停止
。为了证明这不是我的任何code的工人,我添加了一个调用日志记录功能的第一线,从来没有见过一个日志。
有没有错误消息,并且 - 真是个奇怪的一点 - 它不是一个一致的问题。完全相同的调用,冻结现在运行良好30秒后。此外,还没有出现任何真正的模式出现时,无论是问题 - 最接近我看到的是,它偶尔会发生在多个任务同时(例如,它可能会影响到所有的任务开始的时候问题发生在任何任务)。
我把它在一个点,该服务可以自动检测并适当地处理它,所以它不是一个紧迫的问题,但仍东西,我想解决,如果一个原因或解决方案中脱颖而出给任何人。
初始化code工作者是个标准的胜利形成的启动,与我的东西开始被调用的的Form_Load。
静态类节目
{
///<总结>
///的主入口点的应用程序。
///< /总结>
[STAThread]
静态无效的主要()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(假);
Application.Run(新Form1中());
}
}
公共Form1中()
{
的InitializeComponent();
}
私人无效Form1_Load的(对象发件人,EventArgs的)
{
//做的东西 - 从来没有被击中时的冻结发生。
}
修改:每意见,成立了服务登录一个小型转储与当它看到挂起的过程中,它会创建日志条目。将检查它的明天,看看会发生什么吧。
修改2015年9月4日:小型转储信息:
在转储显示了code停止/停留在退出}静态无效的主要,即:
静态无效的主要()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(假);
Application.Run(新Form1中());
} //< ------这是主线程被冻结。
一切似乎罚款,否则。
我会做一些研究和尝试,以防万一一些变化工人。
修改2015年9月4日#2 :调整了工人的启动,似乎是工作。它的要点是去除窗体的引用,只是使用应用程序上下文(如)
我踩着系统的任务要求和它没有任何问题。我会让它运行在上周末的测试,做在星期二的状态更新。不过很好奇,为什么它会随机打破这样的形式加载。
code因为目前的情况是:
静态类节目
{
///<总结>
///的主入口点的应用程序。
///< /总结>
[STAThread]
静态无效的主要()
{
Application.Run(新AppContext());
}
}
类AppContext:ApplicationContext中
{
公共AppContext()
{
//做的东西
}
}
每最后一个音符,拉动表格位出它一起似乎已经解决了这一问题。在这一点上我假设服务器2012不喜欢的东西有关winform应用程序不显示在某些情况下,因为它的工作大部分时间并没有什么形式的code就变了。
服务:
//创建一个临时文件夹和可执行文件复制到其中
//(因此源的exe并不总是在使用中,并且可以被换出)
进程p =新的Process();
的ProcessStartInfo磅=新的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();
如果需要的话//读取标准输出,杀死并重新安排,如果出现被冻结,等等。
工人:
静态类节目
{
///<总结>
///的主入口点的应用程序。
///< /总结>
[STAThread]
静态无效的主要()
{
Application.Run(新AppContext());
}
}
类AppContext:ApplicationContext中
{
公共AppContext()
{
//做的东西
}
}
I have a Windows service set up to manage custom .Net tasks. Organization is:
-Windows Service monitors a schedule and starts a worker .exe as needed.
-Worker .exe (lightweight winform app) uses a command line argument to pull up a DLL (plugin) and run some code.
This has been working well for months. I recently migrated it to Server 2012 (from 2008 IIRC) - this may be unrelated but it's hard to tell. Since some time after the migration, I've encountered an issue where the worker .exe "starts" after being called by a process.start(), but doesn't reach my code. No errors or anything, it just seems to freeze during app load.
The service code that starts it is fairly standard.
// 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.
At that point, the worker executable starts up - it appears mostly normal in the task manager. The only thing that tips me off that something's gone wrong is the memory consumption - under normal circumstances the worker hits around 5MB during launch and grows to reflect the task, but when the process freezes it only reaches around 2MB and stops.
As proof that it's not any of my code in the worker, I've added a call to a logging function as the very first line and never seen a log.
There are no error messages, and - the really strange bit - it isn't a consistent issue. The exact same call that freezes now will run fine 30 seconds later. There also doesn't appear to be any true pattern to when the issue occurs either - the closest thing I'm seeing is that it occasionally happens to multiple tasks at once (e.g. it might be affecting all tasks started at the time when the issue occurs with any task).
I have it at a point where the service can automatically detect it and handle it appropriately, so it's not an urgent issue, but still something I'd like to fix if a cause or solution stands out to anyone.
Init code of worker is just a standard win forms startup, with my stuff starting to get called in 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.
}
Edit: Per comments, set up the service to log a minidump with the log entry it creates when it sees a hung process. Will check on it tomorrow and see what comes of it.
Edit Sept 4, 2015: Minidump info:
The minidump shows the code stopped/stuck at the exiting } of static void main, i.e.:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
} // <------ This is where the main thread is frozen.
Everything seems fine otherwise.
I'm going to do some research and try some changes to the worker just in case.
Edit Sept 4 2015 #2:Adjusted the worker startup and it seems to be working. The gist of it is removing the Form reference and just using application context (e.g. codeproject sample)
I pounded the system with task requests and it didn't have any issues. I'll let it run over the weekend as a test and do a status update on Tuesday.Still curious about why it would randomly break like that with the form load.
Code as it stands now:
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
}
}
Per last note, pulling the form bit out of it all together appears to have fixed the issue. At this point I'm assuming that server 2012 doesn't like something about a winform app not being displayed in certain situations; since it worked most of the time and nothing had changed in the form's code.
Service:
// 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:
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
}
}
这篇关于C#应用程序挂起随机抽取的Process.Start调用时()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!