Приложение C # зависает случайным образом при вызове из Process.Start ()

У меня есть служба Windows, настроенная для управления пользовательскими задачами .Net. Организация это:

-Windows Service отслеживает расписание и при необходимости запускает рабочий EXE-файл.

-Worker .exe (легкое приложение winform) использует аргумент командной строки для загрузки библиотеки DLL (плагина) и запуска некоторого кода.

Это хорошо работает уже несколько месяцев. Я недавно перенес его на Server 2012 (из IIRC 2008 года) - это может быть не связано, но трудно сказать. Спустя некоторое время после миграции я столкнулся с проблемой, когда рабочий .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 - в диспетчере задач он обычно выглядит нормально. Единственное, что подсказывает мне, что что-то пошло не так, - это потребление памяти - в нормальных условиях рабочий достигает около 5 МБ во время запуска и увеличивается, чтобы отразить задачу, но когда процесс зависает, он достигает только около 2 МБ и останавливается.

В качестве доказательства того, что это не мой код в worker, я добавил вызов функции ведения журнала в качестве самой первой строки и никогда не видел журнала.

Сообщений об ошибках нет, и, что действительно странно, это не постоянная проблема. Тот же самый вызов, который сейчас зависает, будет нормально работать через 30 секунд. Также, похоже, нет какой-либо истинной закономерности в том, когда возникает проблема - самое близкое, что я вижу, это то, что иногда это происходит с несколькими задачами одновременно (например, это может повлиять на все задачи, запущенные в то время, когда проблема возникает с любой задачей).


У меня это есть в момент, когда служба может автоматически обнаруживать и обрабатывать ее соответствующим образом, поэтому это не срочная проблема, но все же что-то, что я хотел бы исправить, если причина или решение кому-либо выделяется.


Код инициализации worker - это просто стандартный запуск форм выигрыша, и мои вещи начинают вызываться в 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.
}

Изменить: в комментариях настройте службу для регистрации минидампа с записью журнала, которую он создает, когда видит зависший процесс. Завтра проверю и посмотрю, что из этого выйдет.


Изменить 4 сентября 2015 г.: информация о минидампе:

Минидамп показывает, что код остановлен / застрял при выходе} из static void main, то есть:

static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
} // <------ This is where the main thread is frozen.

В остальном вроде все нормально.

Я собираюсь провести небольшое исследование и на всякий случай попробовать некоторые изменения в worker.


Редактировать от 4 сентября 2015 г. № 2: скорректирован запуск работника, и он, похоже, работает. Суть этого в том, чтобы удалить ссылку на форму и просто использовать контекст приложения (например, пример кода проекта)

Я забил систему запросами задач, и у нее не было никаких проблем. Я позволю ему поработать на выходных в качестве теста и обновлю статус во вторник. Все еще любопытно, почему он так случайно ломается при загрузке формы.

Код в его нынешнем виде:

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

person user1874135    schedule 03.09.2015    source источник
comment
Я думаю, вам следует опубликовать код инициализации для этого рабочего .exe.   -  person Jeff Prince    schedule 04.09.2015
comment
Обновлено - это просто стандартный (сгенерированный VS) материал инициализации до form_load, после чего мой материал (обычно) срабатывает. Вызов журнала в качестве первой строки form_load - вот как я понял, что он не достиг этой точки.   -  person user1874135    schedule 04.09.2015
comment
Вы пробовали сбросить процесс, когда он завис, и загрузить в VS / WinDBG, чтобы узнать, где он завис?   -  person Rich Turner    schedule 04.09.2015
comment
Вы пробовали запустить эту программу WinForms в автономном режиме, чтобы проверить, запускается ли она? Я думаю, у вас что-то не так с самим определением формы, что делает невозможным ее инициализацию.   -  person Jeff Prince    schedule 04.09.2015
comment
Пока нет - обычно мне не нужно выполнять удаленную отладку, поэтому я не совсем уверен во всех доступных инструментах. Редактировать, потому что shift + enter vs enter: я внесу некоторые изменения в службу и попробую, когда это произойдет в следующий раз.   -  person user1874135    schedule 04.09.2015
comment
@JeffPrince У меня есть - большую часть времени он работает отлично, и я никогда не видел, чтобы он зависал во время отладки. Автономный запуск - это то, как я отлаживаю и определенные плагины (поскольку они просто библиотеки классов). Изменить: просто дважды проверьте через командную строку, и все сработало без проблем.   -  person user1874135    schedule 04.09.2015
comment
Интересно, не нравится ли ему тот CreateNoWindow, который вы указали.   -  person Jeff Prince    schedule 04.09.2015
comment
@JeffPrince Возможно, прошло довольно много времени с тех пор, как я установил основу системы - может быть, обновление .Net изменило поведение? Я настроил службу на сохранение дампа с журналом, который он создает, когда видит зависший процесс - я посмотрю, покажет ли это что-нибудь завтра утром, и продолжу здесь.   -  person user1874135    schedule 04.09.2015
comment
Обновленный вопрос с информацией о дампе. Думаю, я собираюсь заменить воркера на консольное приложение или посмотреть, что я могу настроить при его запуске.   -  person user1874135    schedule 04.09.2015
comment
(Могу напоследок прокомментировать: D) Видел последние обновления. Надеюсь, что это работает!   -  person Pomme De Terre    schedule 05.09.2015


Ответы (2)


Я пока не могу добавить комментарий к вашему сообщению (я буду уничтожен другим пользователем stackoverflow за это, но ...)

Я столкнулся с проблемой, очень похожей на вашу. Моя проблема исходила из сеанса, в котором запущена служба. Во время миграции служба запускалась в «Сессии 0» в новой ОС, а не как «системная» программа. Он был выпущен с разрешения нашей программы для работы через службу. Может тебе стоит проверить этот момент.

Извините, если я скажу это как ответ, а не в комментарии

person Pomme De Terre    schedule 04.09.2015
comment
Нет проблем, я понимаю боль (сейчас только 11 повторений). Grrr, отредактируйте еще раз, потому что Enter vs shift + enter: в этом случае служба работает с учетными данными суперадминистратора в соответствующем сеансе. - person user1874135; 04.09.2015
comment
Вы получили эту информацию от своей службы? Даже Microsoft не смогла решить нашу проблему ... Мы выяснили это, отчаянно попробовав несколько вещей. На всякий случай перепроверьте. По крайней мере, вы будете уверены: P - person Pomme De Terre; 05.09.2015

Согласно последней заметке, извлечение бита формы из всего этого, похоже, устранило проблему. На этом этапе я предполагаю, что серверу 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
    }
}
person user1874135    schedule 08.09.2015