从Process.Start()

时间:2015-09-03 19:46:51

标签: c# .net windows-services windows-server-2012

我有一个Windows服务设置来管理自定义.Net任务。组织是:

-Windows Service监视计划并根据需要启动worker .exe。

-Worker .exe(轻量级winform应用程序)使用命令行参数来提取DLL(插件)并运行一些代码。

这已经好几个月了。我最近将它迁移到Server 2012(从2008 IIRC) - 这可能是不相关的,但很难说。从迁移后的一段时间开始,我遇到了一个问题,即在由process.start()调用后,worker .exe“启动”,但是没有到达我的代码。没有错误或任何东西,它似乎在应用程序加载期间冻结。

启动它的服务代码是相当标准的。

// 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.

此时,工作程序可执行文件启动 - 它在任务管理器中显得正常。唯一可以让我知道出现问题的是内存消耗 - 在正常情况下,工作人员在启动时会大约5MB,并且会增长以反映任务,但是当进程冻结时它只会达到大约2MB并停止。

为了证明这不是我工作中的任何代码,我已经添加了对日志功能的调用作为第一行并且从未见过日志。

没有错误消息,而且 - 真的很奇怪 - 这不是一个一致的问题。现在冻结的完全相同的呼叫将在30秒后运行良好。当问题出现时似乎也没有任何真实的模式 - 我所看到的最接近的事情是偶尔会发生多个任务(例如,它可能会影响问题发生时开始的所有任务)任何任务都会发生。)

我有一个服务可以自动检测并适当处理它的地方,所以这不是一个紧急的问题,但如果某个原因或解决方案对任何人都很突出,我还是想解决这个问题。

worker的init代码只是一个标准的win form启动,我的东西开始在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.
}

编辑:根据评论,设置服务以使用它在看到挂起进程时创建的日志条目记录minidump。明天会检查它,看看会发生什么。

编辑2015年9月4日:Minidump信息:

minidump显示代码在静态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
    }
}

2 个答案:

答案 0 :(得分:2)

我无法在你的帖子上添加评论(我会被其他stackoverflow用户销毁,但是......)

我遇到了与你的问题非常相似的问题。我的问题来自于服务启动的会话。在迁移期间,服务在会话0&#34;在新的操作系统中,而不是作为一个&#34;系统&#34;程序。它是在我们的程序允许的情况下发布的,以便运行该服务。 也许你应该检查这一点。

很抱歉,如果我将其作为答案而非评论

答案 1 :(得分:0)

最后一点,将表单位拉出来似乎已经解决了问题。在这一点上,我假设服务器2012不喜欢在某些情况下没有显示的winform应用程序;因为它大部分时间都有效,而且形式的代码没有任何改变。

服务:

// 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.

工人:

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
    }
}